[BUG] API 400 error: tool_reference.tool_name exceeds 64 characters when ToolSearch loads MCP plugin tools
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Issue Summary
When using ToolSearch with keyword-based queries (e.g., +semgrep scan, +analyzer ruff), Claude Code fails with an API 400 error if discovered MCP plugin tools have names that, when embedded in tool_reference blocks inside tool_result content, exceed 64 characters.
---
Error Message
400 {
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "messages.30.content.0.tool_result.content.0.tool_reference.tool_name: String should have at most 64 characters"
},
"request_id": "req_011CXckKEcZ1SFfFUyjUF2qr"
}
````
---
## Reproduction Steps
1. Install an MCP plugin with a multi-part naming convention
Example: `semgrep-plugin@semgrep` from the Semgrep marketplace.
2. Enable the plugin in `.claude/settings.json`:
```json
{
"enabledPlugins": {
"semgrep-plugin@semgrep": true
}
}
````
3. Start a Claude Code session.
4. Use a keyword-based ToolSearch query that matches plugin tools:
```
+semgrep scan
```
5. After tools are loaded (debug log shows *Dynamic tool loading: 10/67 deferred tools included*), the next API request fails immediately with a 400 error.
---
## Debug Log Evidence
2026-01-30T02:08:29.176Z [DEBUG] ToolSearchTool: keyword search for "+analyzer ruff vulture", found 5 matches
2026-01-30T02:08:32.347Z [DEBUG] ToolSearchTool: keyword search for "+semgrep scan", found 5 matches
2026-01-30T02:08:32.515Z [DEBUG] Dynamic tool loading: found 10 discovered tools in message history
2026-01-30T02:08:32.517Z [DEBUG] Dynamic tool loading: 10/67 deferred tools included
2026-01-30T02:08:32.854Z [ERROR] API error (attempt 1/11): 400 {
"type":"error",
"error":{
"type":"invalid_request_error",
"message":"messages.30.content.0.tool_result.content.0.tool_reference.tool_name: String should have at most 64 characters"
}
}
---
## Analysis
MCP plugin tools follow the naming pattern:
mcp__plugin_<plugin-name>_<server-name>__<tool-name>
For the `semgrep-plugin@semgrep` plugin (which defines an MCP server named `sg`), this produces tool names such as:
| Tool Name | Length |
| -------------------------------------------------------------- | ------ |
| `mcp__plugin_semgrep-plugin_sg__semgrep_scan` | 43 |
| `mcp__plugin_semgrep-plugin_sg__semgrep_rule_schema` | 50 |
| `mcp__plugin_semgrep-plugin_sg__get_supported_languages` | 54 |
| `mcp__plugin_semgrep-plugin_sg__get_abstract_syntax_tree` | 55 |
| `mcp__plugin_semgrep-plugin_sg__semgrep_scan_supply_chain` | 56 |
| `mcp__plugin_semgrep-plugin_sg__semgrep_scan_with_custom_rule` | 60 |
**Paradox:** All tool names are under 64 characters, yet the API rejects them.
This suggests one of the following:
1. Additional characters are added when constructing `tool_reference` blocks (prefixes, suffixes, escaping, etc.).
2. A different field is being validated that includes extra context beyond the raw tool name.
3. The `tool_reference` structure combines multiple fields into the `tool_name` validation.
The error path
`messages.30.content.0.tool_result.content.0.tool_reference.tool_name`
indicates the failure occurs inside a `tool_result` message, specifically within ToolSearch results where tool references are embedded.
---
## Workaround
Using **direct tool selection** with the `select:` prefix bypasses the issue:
ToolSearch query: "select:mcp__analyzer__ruff-check" ✅ Works
ToolSearch query: "+analyzer ruff" ❌ Fails
---
## Environment
* Claude Code version: **2.1.25**
* OS: **Linux 6.17.9-76061709-generic (Pop!_OS / Ubuntu)**
* Affected plugin: **semgrep-plugin@semgrep**
(potentially any plugin with long naming schemes)
### Plugin MCP Server Configuration (`.mcp.json`)
```json
{
"mcpServers": {
"sg": {
"command": "semgrep",
"args": ["mcp"]
}
}
}
What Should Happen?
What Should Happen?
- ToolSearch keyword queries should work regardless of MCP plugin tool name length.
The current naming scheme
mcp__plugin_<plugin>_<server>__<tool>
is deterministic and correct, but it should not cause API failures.
- Tool names in
tool_referenceblocks should be validated or normalized before API submission.
If the API enforces a 64-character limit on tool_reference.tool_name, Claude Code should apply one of the following strategies:
- Truncate or hash long tool names to fit within the limit
- Use a shorter alias or reference ID in
tool_referenceblocks - Adjust the plugin tool naming scheme to be more compact
- The MCP plugin tool naming convention should explicitly account for length constraints.
Possible approaches include:
- Shorter prefixes (e.g.,
mcp_p_instead ofmcp__plugin_) - Hash-based plugin identifiers (e.g.,
mcp__p_abc123__tool_name) - Omitting redundant segments when the plugin name and server name are identical
- Errors should be handled gracefully rather than causing hard failures.
If a tool name exceeds API limits, Claude Code should:
- Log a warning
- Skip the problematic tool or fall back to a safe alternative
- Avoid crashing the entire request
- Direct selection (
select:) and keyword search should behave consistently.
Both mechanisms should either succeed or fail for the same set of tools. The current asymmetry between select: and keyword-based ToolSearch is confusing and unexpected.
Error Messages/Logs
2026-01-30T02:08:17.665Z [DEBUG] Metadata string for dispatch:
2026-01-30T02:08:17.665Z [DEBUG] <command-message>dispatch</command-message>
<command-name>/dispatch</command-name>
<command-args>now, run the code quality agent on ELT layer only, use the tools available for better analysis. You can
2026-01-30T02:08:29.000Z [DEBUG] executePreToolHooks called for tool: ToolSearch
2026-01-30T02:08:29.176Z [DEBUG] ToolSearchTool: keyword search for "+analyzer ruff vulture", found 5 matches
2026-01-30T02:08:29.354Z [DEBUG] Dynamic tool loading: found 5 discovered tools in message history
2026-01-30T02:08:29.356Z [DEBUG] Dynamic tool loading: 5/67 deferred tools included
2026-01-30T02:08:32.164Z [DEBUG] executePreToolHooks called for tool: ToolSearch
2026-01-30T02:08:32.347Z [DEBUG] ToolSearchTool: keyword search for "+semgrep scan", found 5 matches
2026-01-30T02:08:32.515Z [DEBUG] Dynamic tool loading: found 10 discovered tools in message history
2026-01-30T02:08:32.517Z [DEBUG] Dynamic tool loading: 10/67 deferred tools included
2026-01-30T02:08:32.517Z [DEBUG] attribution header x-anthropic-billing-header: cc_version=2.1.25.b62; cc_entrypoint=cli;
2026-01-30T02:08:32.518Z [DEBUG] [API:request] Creating client, ANTHROPIC_CUSTOM_HEADERS present: false, has Authorization header:
false
2026-01-30T02:08:32.518Z [DEBUG] [API:auth] OAuth token check starting
2026-01-30T02:08:32.518Z [DEBUG] [API:auth] OAuth token check complete
2026-01-30T02:08:32.854Z [ERROR] API error (attempt 1/11): 400 400 {"type":"error","error":{"type":"invalid_request_error","message
":"messages.30.content.0.tool_result.content.0.tool_reference.tool_name: String should have at most 64
characters"},"request_id":"req_011CXckKEcZ1SFfFUyjUF2qr"}
2026-01-30T02:08:32.854Z [ERROR] Error in non-streaming fallback: 400 {"type":"error","error":{"type":"invalid_request_error","mess
age":"messages.30.content.0.tool_result.content.0.tool_reference.tool_name: String should have at most 64
characters"},"request_id":"req_011CXckKEcZ1SFfFUyjUF2qr"}
2026-01-30T02:08:32.854Z [ERROR] Error: Error: 400 {"type":"error","error":{"type":"invalid_request_error","message":"messages.30.c
ontent.0.tool_result.content.0.tool_reference.tool_name: String should have at most 64
characters"},"request_id":"req_011CXckKEcZ1SFfFUyjUF2qr"}
at generate (/$bunfs/root/claude:144:37655)
at makeRequest (/$bunfs/root/claude:161:5435)
at processTicksAndRejections (native:7:39)
Steps to Reproduce
Prerequisites
- Install an MCP plugin with a multi-part naming scheme. For example, install semgrep-plugin from the Semgrep marketplace:
claude plugins add semgrep-plugin@semgrep
- Enable the plugin in your project's .claude/settings.json:
{
"enabledPlugins": {
"semgrep-plugin@semgrep": true
}
}
- Verify the plugin creates tools with long names (pattern: mcp__plugin_<plugin-name>_<server-name>__<tool-name>):
- mcp__plugin_semgrep-plugin_sg__semgrep_scan_with_custom_rule (60 chars)
Reproduction Steps
- Start a new Claude Code session:
claude
- Trigger a keyword-based ToolSearch that matches the plugin's tools. Either:
- Option A - Direct ToolSearch:
Use ToolSearch to find semgrep scanning tools
- Option B - Via agent/command that uses ToolSearch internally:
/dispatch run the code quality agent on ELT layer, use available MCP tools
- Observe Claude Code use ToolSearch with a keyword query like +semgrep scan
- Error occurs on the next API request after the tools are loaded
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.25 (Claude Code)
Platform
Anthropic API
Operating System
Other Linux
Terminal/Shell
Other
Additional Information
_No response_
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗