ANTML encoding: & in structured output tool parameters is not unescaped before surfacing errors/results to agent
Summary
When an agent uses the outputFormat (structured output) feature and returns JSON with &, <, >, ", or ' in string values, the ANTML transport layer XML-encodes these characters (& → & etc.) in the tool parameter envelope but fails to unescape them before surfacing the error or result back to the agent. This creates a multi-turn feedback loop where the agent burns many turns trying to fix what it perceives as self-caused bad output.
Steps to reproduce
- Configure a
query()call withoutputFormat: { type: "json_schema", schema: {...} } - Have the agent produce a JSON result containing
&in a string value (e.g.{"title": "Qualification & Onboarding"}) - Observe the SDK surface an error to the agent referencing XML encoding of
& - The agent enters a repair loop attempting to manually escape
&→&, then various other combinations
Root cause
The SDK uses ANTML (Anthropic's XML markup language) to encode tool inputs and outputs at the API layer. When the agent calls the structured output tool with {"title": "Qualification & Onboarding"}, the & is XML-encoded in the ANTML envelope as &. The SDK either:
- Fails to parse the XML (treating the unescaped
&as malformed XML), or - Surfaces the encoded form to the agent as an error ("your output contained invalid XML character
&")
The agent then reasons that it must escape & as & in its JSON, which is incorrect — JSON and XML are different serialization formats with different escaping rules. This creates the feedback loop.
Impact
- Observed 77+ turns burned on a single step in production
- Any domain content containing
&,<,>,", or'in string values triggers this - Eventually either returns truncated/malformed output or exhausts turn budget
Expected behavior
The SDK should unescape XML entities (& → &, < → <, etc.) from ANTML-encoded tool parameter values before:
- Surfacing errors to the agent about structured output validation
- Returning the
structured_outputfield in the result message
The agent produces perfectly valid JSON. The encoding issue is entirely in the SDK's transport layer and should be invisible to the agent.
Workaround applied upstream
Added an agent prompt note instructing the agent never to manually XML-escape JSON string values and to return output as-is on encoding errors (at most one retry). This stops the repair loop but does not fix the root cause.
Environment
@anthropic-ai/claude-agent-sdkversion0.2.101- Related known issue:
anthropics/claude-agent-sdk-typescript#277(SDK silently dropsoutputFormatenforcement for non-trivial schemas)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗