[Bug] Anthropic API Error: Opus 4.8 produces invalid schema-conformant output on large nested CJK payloads; schema retry loops stall workflow

Open 💬 2 comments Opened Jun 24, 2026 by snwsnwsnw

Bug Description
Title: Workflow + StructuredOutput: Opus 4.8 produces invalid schema-conformant output on large/nested CJK payloads; harness retry loops for 8–20 min and stalls the pipeline Component: Claude Code — Workflow tool, schema-enforced subagent output (StructuredOutput) Model: claude-opus-4-8 (1M context) Severity: Medium — no data loss, but burns minutes + tokens per agent and can hang a workflow; failure looks like "still running." Summary When a Workflow subagent is invoked with a schema and must emit a large, deeply-nested, CJK-heavy JSON object, Opus 4.8 intermittently fails to produce a valid object. The harness rejects it (Output does not match required schema: ...) and the agent retries the same malformed shape repeatedly. There is no fail-fast / degrade path, so the agent spins for 8–20 minutes (file mtime frozen). Because it is a pipeline() stage that never resolves, it stalls downstream stages and the workflow appears to "run" indefinitely. Two distinct failure modes observed (same root: large structured output is unreliable): 1. Tool-grammar leakage — find agent emitted, inside a JSON string value: StructuredOutput input={"dimensionAssessment": "...DROP 後 runtime Unknown column 炸。</dimensionAssessment>\n<parameter name=\"findings\">[{\"id\":\"C1\",... 1. The model closed the field with an XML end-tag and opened <parameter name="findings"> — mixing Anthropic's XML-tagged tool-call grammar into what the harness expects as a pure-JSON argument. It also tried to pass the findings array as a JSON string. Rejection (repeated ×5): root: must have required property 'findings' 2. Required-field omission on long output — verify agent (different schema) produced valid JSON but dropped a required field 5 times in a row: {"isReal": true, "adjustedSeverity": "P1", "confidence": "high", "planAlreadyHandles": false, "threeStageEvidence": {"pattern": "...(very long)..."}, "verdict": "..."} ← missing "fixAssessment" 2. Inputs were 2700–3200 chars; the model appears to exhaust budget on the long threeStageEvidence and omit the trailing required field. Rejection (repeated ×5): root: must have required property 'fixAssessment' Key observation: the generic schema-error message does not tell the model what it did wrong or which value to fix, so retries reproduce the same error. Five identical-error retries provided zero correction signal. Scale of incident: a ~60-agent review workflow (18 dimensions × find+verify). Agents on "list many files/lines" dimensions (completeness, drop-column enumeration, cross-service writepath) were the ones that crashed; simple dimensions succeeded. Impact - Wasted wall-clock (8–20 min/stuck agent) and tokens on doomed retries. - A stalled pipeline stage can hang the whole workflow (only a call-site .catch or a retry cap saves it). - Low observability: /workflows shows "running," not "retry-failing ×5." Suggested fixes (harness side) 1. Cap schema retries (e.g. 3) then resolve the agent() call to a structured error / null promptly, so .catch / pipeline-drop engages instead of spinning for minutes. 2. Targeted re-prompt instead of generic error: on rejection, tell the model exactly which field is missing/invalid and "emit pure JSON, no XML <parameter>/</field> tags, arrays as arrays not strings." The generic must have required property X is too weak to correct mode-1 and mode-2. 3. Auto-repair the common mode-1 leakage (strip </field> / <parameter ...> and re-parse) before failing. 4. Degrade to free-text capture after N failures so the finding isn't lost. 5. Surface retry-stall in /workflows ("schema-retry ×5") so it reads as failing, not running. Workaround that fixed it (user side) - Shrink the per-agent output: prompt caps (≤N findings/dimension, ≤3 sentences/field, evidence = file:line list only, no pasted code) + an explicit "arrays are top-level params, never stuff into a string, no XML tags" instruction. - Restart only the affected agents with Workflow({scriptPath, resumeFromRunId}) — cached agents return instantly, only the edited prompts re-run.

Environment Info

  • Platform: darwin
  • Terminal: iTerm.app
  • Version: 2.1.187
  • Feedback ID: 74cbb289-d328-4abe-9dc9-41465710c8d5

Errors

[]

View original on GitHub ↗

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