bug: uwf-claude-code silently fails when Claude Code exits without result line #574

Closed
opened 2026-05-30 04:42:08 +00:00 by xiaoju · 0 comments
Owner

Problem

When Claude Code's stream-json output is missing the final type: "result" line (due to timeout, OOM, API error, or signal kill), parseClaudeCodeStreamOutput returns null and the adapter throws a generic error:

Claude Code returned unparseable output (first 200 chars): {"type":"system","subtype":"init",...}

This is misleading — the output is parseable, it's just incomplete (no result line).

Root Cause

assembleResult() in session-detail.ts returns null when state.resultLine === null. Then processClaudeOutput() in claude-code.ts throws with a message that implies the output format is wrong, when the real issue is that Claude Code exited prematurely.

Observed Behavior

  • Thread #573 background exec: planner succeeded, developer step spawned Claude Code
  • Claude Code ran ~10 minutes, output system/assistant/user lines, but no result line
  • Adapter threw, background worker stopped, thread stuck at idle with currentRole: developer

Proposed Fix

  1. Distinguish incomplete vs unparseable: If resultLine is null but turns were parsed, report "Claude Code exited without result (N turns parsed, possible timeout/crash)" instead of "unparseable output"
  2. Fallback extraction: When no result line exists but assistant turns are present, extract the last assistant text as output (best-effort)
  3. Include exit code/stderr: Pass stderr and exit code through to the error message for diagnosis
  4. Consider retry: Background worker could retry the step once on this specific failure mode

Files

  • packages/workflow-agent-claude-code/src/claude-code.tsprocessClaudeOutput()
  • packages/workflow-agent-claude-code/src/session-detail.tsassembleResult()

— 小橘 🍊(NEKO Team)

## Problem When Claude Code's `stream-json` output is missing the final `type: "result"` line (due to timeout, OOM, API error, or signal kill), `parseClaudeCodeStreamOutput` returns `null` and the adapter throws a generic error: ``` Claude Code returned unparseable output (first 200 chars): {"type":"system","subtype":"init",...} ``` This is misleading — the output **is** parseable, it's just incomplete (no result line). ## Root Cause `assembleResult()` in `session-detail.ts` returns `null` when `state.resultLine === null`. Then `processClaudeOutput()` in `claude-code.ts` throws with a message that implies the output format is wrong, when the real issue is that Claude Code exited prematurely. ## Observed Behavior - Thread #573 background exec: planner succeeded, developer step spawned Claude Code - Claude Code ran ~10 minutes, output system/assistant/user lines, but no result line - Adapter threw, background worker stopped, thread stuck at `idle` with `currentRole: developer` ## Proposed Fix 1. **Distinguish incomplete vs unparseable**: If `resultLine` is null but turns were parsed, report "Claude Code exited without result (N turns parsed, possible timeout/crash)" instead of "unparseable output" 2. **Fallback extraction**: When no result line exists but assistant turns are present, extract the last assistant text as output (best-effort) 3. **Include exit code/stderr**: Pass stderr and exit code through to the error message for diagnosis 4. **Consider retry**: Background worker could retry the step once on this specific failure mode ## Files - `packages/workflow-agent-claude-code/src/claude-code.ts` — `processClaudeOutput()` - `packages/workflow-agent-claude-code/src/session-detail.ts` — `assembleResult()` — 小橘 🍊(NEKO Team)
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: uncaged/workflow#574