[BUG] API 400 error: tool_reference.tool_name exceeds 64 characters when ToolSearch loads MCP plugin tools

Resolved 💬 3 comments Opened Jan 30, 2026 by kaiohenricunha Closed Feb 2, 2026

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?

  1. 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.

  1. Tool names in tool_reference blocks 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_reference blocks
  • Adjust the plugin tool naming scheme to be more compact
  1. The MCP plugin tool naming convention should explicitly account for length constraints.

Possible approaches include:

  • Shorter prefixes (e.g., mcp_p_ instead of mcp__plugin_)
  • Hash-based plugin identifiers (e.g., mcp__p_abc123__tool_name)
  • Omitting redundant segments when the plugin name and server name are identical
  1. 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
  1. 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

  1. 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

  1. Enable the plugin in your project's .claude/settings.json:

{
"enabledPlugins": {
"semgrep-plugin@semgrep": true
}
}

  1. 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

  1. Start a new Claude Code session:

claude

  1. Trigger a keyword-based ToolSearch that matches the plugin's tools. Either:
  1. Option A - Direct ToolSearch:

Use ToolSearch to find semgrep scanning tools

  1. Option B - Via agent/command that uses ToolSearch internally:

/dispatch run the code quality agent on ELT layer, use available MCP tools

  1. Observe Claude Code use ToolSearch with a keyword query like +semgrep scan
  2. 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_

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗