`AskUserQuestion` rejects valid-looking input with an opaque `could not be parsed as JSON` error
Type: bug
Environment
- Claude Code version: 2.1.220
- OS: macOS 26.5.2 (Darwin 25.5.0)
- Shell: zsh
- Platform: Claude subscription
- Model: claude-opus-5 (also observed on claude-opus-4-8 and claude-fable-5)
What happened
AskUserQuestion calls fail with:
<tool_use_error>InputValidationError: AskUserQuestion was called with input that could not be parsed as JSON.
You sent (first 200 of 874 bytes): {"questions": [{"question":"...
Three separate problems compound here:
- The error does not say where parsing failed. No byte offset, no line/column, no JSON pointer — only a truncated echo of the first 200 bytes. The model has no way to tell whether the problem is an unterminated string, a stray character, or something else, so the natural next step is a blind retry.
- Retries are systematically wasted. In this transcript store the failure appears in 88 of 5 096 transcript files, and it typically appears 2–6 times consecutively in a session before the model gives up and falls back to plain text. Each retry costs a full round trip while a human is waiting on the dialog.
- The failure is not purely a size limit, but behaves like a truncation. The echoed payload is reported as
first 200 of N bytes; failing payloads were observed at 874 B, 1 544 B, 1 971 B and 2 663 B, while a 1 247 B payload parsed fine. In two cases the echoed prefix was itself cut mid-string, which suggests the tool input is being truncated somewhere in transport before validation, rather than rejected by a documented limit.
A separate but related observation: passing the same content as a structured questions parameter succeeded where an equivalent raw-JSON string payload repeatedly failed, including for payloads under 1.3 KB that were valid JSON with correctly escaped quotes.
Expected
- The validation error names the failure location (byte offset or JSON pointer) and the reason, so a repair is targeted rather than a guess.
- If there is a size limit on tool input, it is documented and reported as a limit ("input is N bytes, limit is M") instead of a parse error.
- If input is truncated in transport, that is a bug and the truncation should not be reported as malformed input.
Repro
- Call
AskUserQuestionwith aquestionspayload of roughly 0.9–2.7 KB containing non-ASCII text (accented Latin characters and typographic quotes). - Observe
InputValidationError: ... could not be parsed as JSON, with only the first 200 bytes echoed back. - Retry the identical payload — it fails identically. Shrink the payload below ~1.2 KB and strip non-ASCII punctuation — it usually succeeds.
Note: this reproduces with no PreToolUse hook registered on AskUserQuestion; the failure happens before hooks run (verified locally — a hook that logs every invocation never sees these calls).
Impact
This is the single most frequent tool-level defect in our data. Every failure blocks a question that a human is actively waiting for, and because the error carries no diagnosis the model burns 2–6 attempts before working around it. We ended up writing a local pre-flight JSON linter purely to avoid this round trip.