XML tool-call converter drops content parameter (size + parallel-batch triggers)

Resolved 💬 3 comments Opened May 6, 2026 by MicrotronX Closed Jun 4, 2026

Summary

Tool-calls invoked from main-context with a <parameter name="content"> value larger than approximately 5500-11000 chars are converted to JSON-RPC bodies where arguments.content is "" (empty) and the original content text leaks as XML markup into a sibling parameter (e.g. summary_l1). Below the threshold the same tool-call works correctly. The same content delivered via a Background-Subagent (Agent-Tool with internal tool-use) goes through correctly — confirming the bug is in the main-context XML→JSON conversion path.

Update 2026-05-06: Bug also fires at much smaller body sizes (~150 words / ~800 chars) when the tool-call is part of a parallel-batch with other tool-calls in the same message. Parallel-batch position appears to be a confounding factor independent of body size. Threshold may not be size-only.

Reproduction

  1. Use any MCP server tool that takes a content: string parameter (mxLore mx_create_doc works as live target)
  2. From main-context, invoke tool with content = ~15000 chars Markdown body containing tables, unicode arrows, code blocks
  3. Observe immediate (<1s) reject from server with content-validator error
  4. Repeat with same content via Agent tool (general-purpose subagent) → succeeds

Server-side evidence

  • HTTP body received intact: bytes=15636 chars=15511 (correct UTF-8 size)
  • JSON parser accepts body
  • arguments.content field is empty string in parsed JSON
  • Body tail shows ...\"master\"]</parameter>\n</invoke>\n\"},\"_meta\":... — XML closing tags landed as TEXT inside a JSON string value
  • 0 transport-level errors, dozens of validator-level "got 0 chars" rejects across logs

Threshold pattern

| content size | result |
|---|---|
| 4500 chars | success |
| 2800 chars | success |
| ~800 chars (parallel-batch context) | fail |
| 11488 chars | fail |
| 15511 chars | fail |

Threshold inconsistent at ~5500-11000 chars in solo calls; smaller sizes also fail when in parallel-batch with other tool-calls. Current Claude Code Opus 4.7 1M-context build.

Workaround

Delegate the call to a Background-Subagent: subagent constructs the tool-call internally using its own JSON args path, not the main-context XML-parameter encoding. Same content, same MCP server, same tool — succeeds reliably.

Environment

  • Claude Code Opus 4.7 (1M context)
  • Tool: any MCP server with content: string parameter
  • Repro confirmed: Win32 stdio + Windows MCP-Proxy bridge AND HTTP Streamable MCP — bug is upstream of both bridge layers
  • Date first observed: 2026-04-27
  • Date re-confirmed in parallel-batch context: 2026-05-06

Impact

Silent data-loss: the user-visible error is a server-side validator reject saying "content required", which masks the real bug location. Reporters chase server-side phantoms instead of escalating to CC-CLI. MCP server implementers have to add empty-body server-side guards as defense-in-depth (see e.g. mxLore Bug#4378 fix in build 112).

View original on GitHub ↗

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