[BUG] Workflow parallel() sub-agent loops forever emitting empty StructuredOutput calls; no retry cap and no per-agent timeout stalls the whole workflow
What's Wrong?
A Workflow parallel() sub-agent invoked with a JSON schema (forced StructuredOutput) entered an unrecoverable loop emitting empty {} StructuredOutput tool calls and never converged. Two distinct defects compound:
1. No retry cap / loop-breaker on repeated empty (invalid) StructuredOutput calls.
The sub-agent's job was to read several files and return a structured summary. After doing its reading (~170 tool calls of legitimate work), it began calling the internal StructuredOutput tool with an empty {} payload — and kept doing so 229 consecutive times (agent transcript grew to ~894 KB) without ever producing a valid payload. The model was even aware it was looping — its own assistant text read:
"I am repeatedly emitting empty calls. Let me write the four-parameter call directly, ordering evidence, summary, ... with real content."
…and then emitted another empty call. There appears to be no detection of repeated identical empty/invalid StructuredOutput calls and no max-retry, so it spins indefinitely, burning tokens.
This is distinct from the closed CLI bug #37904 (where the model refuses to call StructuredOutput, treating it as prompt injection, via the --json-schema flag) — here the model does call it, repeatedly, with empty input, via the multi-agent Workflow path. (#37904's auto-close note asked that similar cases be filed as new issues referencing it.) It's also a different mechanism from the StructuredOutput context-saturation described in #63742.
2. parallel() has no per-agent timeout / stuck-detection, so one wedged agent stalls the whole workflow.
The workflow ran parallel([...]) over three investigation agents, then a Verify phase gated on that barrier. Two agents finished in ~1 min; the third entered the empty-output loop above and never returned. Because parallel() has no per-agent watchdog, the barrier blocked indefinitely, the downstream Verify phase never started, and the run had to be killed manually with TaskStop.
The documented parallel() contract is that a dead/failed agent "resolves to null … so .filter(Boolean) before using the results." But an empty-output retry loop is not detected as failure, so instead of resolving to null and letting the workflow proceed, it hangs.
What Should Happen?
- Detect repeated identical empty/invalid
StructuredOutputcalls; after a small retry cap, fail that agent (soparallel()/pipeline()resolves it tonullper the documented contract) rather than looping forever. - Add a per-agent timeout / watchdog to
parallel()andpipeline()so a single wedged agent cannot stall the entire workflow barrier and downstream phases. On timeout, resolve that agent tonulland continue. - Surface a clear diagnostic (e.g. "agent X exceeded N empty StructuredOutput retries / timed out → resolved to null") instead of a silent indefinite hang.
Possibly relevant context
The stuck agent had accumulated a large context before being asked to emit (it had read several large source files — ~170 prior tool calls). I'm not asserting causation, but "large accumulated context, then forced to emit a multi-field structured object" may be a contributing trigger. The schema was a plain object with ~6 fields (strings, enums, and a string array) — nothing exotic.
Error Messages/Logs
- 229 consecutive
StructuredOutputtool_useevents withinput == {}in the sub-agent transcript (~894 KB JSONL). - Sibling agents in the same
parallel()completed normally and produced valid structured output, so the schema/runtime itself works — this is specific to the one agent that wedged. - No error was emitted; the workflow simply never advanced past the
parallel()barrier until manually stopped.
(Logs sanitized — the agent's task content is omitted as it concerned a private codebase. The failure is in the harness behavior, which is content-independent.)
Environment
- Claude Code: 2.1.176
- Model: Claude Opus 4.8 (1M context) (
claude-opus-4-8[1m]) - Surface: Workflow tool (multi-agent orchestration) —
parallel()with sub-agents using theschema/ forced-StructuredOutputoption - Platform: macOS (darwin)
Related
- #37904 (CLOSED, dup) —
--json-schemainfinite loop, model refuses to call StructuredOutput (CLI surface). Same "infinite loop around StructuredOutput" family, different mechanism + surface. - #63742 (OPEN) — field notes: StructuredOutput context-saturation in a multi-agent workflow (different failure mode).