VSC: webview declares "sdk_stream_ended_no_result had_error" prematurely during long inter-chunk gaps; orphaned AskUserQuestion then triggers "Unhandled case: [object Object]"
Summary
Webview reports sdk_stream_ended_no_result with had_error: true after only ~30s of inter-chunk silence, while the SDK subprocess (claude.exe) continues streaming successfully and writes the completed assistant response to the session JSONL ~55s later. The orphaned-but-legitimate executePermissionRequestHooks call for AskUserQuestion that follows then triggers a renderer-side "Unhandled case: [object Object]" toast — the webview state machine appears to have no transition for "permission request after the stream was declared dead".
End-user impact: the AskUserQuestion UI never renders even though the model produced it; the response is invisibly persisted to the session JSONL. The session looks "stuck" / idle, but on resume the work is intact.
Environment
- Claude Code VSC extension: 2.1.141 (
2.1.141.7ae, claude-vscode entrypoint) - Native binary:
claude.exeat…\anthropic.claude-code-2.1.141-win32-x64\resources\native-binary\claude.exe - VS Code (Code): version 0958016b2a build
- OS: Windows 11 Home 10.0.26200
- Node (extension host): v24.3.0
- Permission mode: default
- Session was resumed (not fresh)
- Workload character: heavy cache read (~243k input tokens cache_read), large output (~6.2k output tokens), long inter-chunk gap during model reasoning
Timeline (from the extension's output log)
All timestamps local (UTC+2). API request ID: req_011Cb3JYmaUhrNyt81a5Rxa2.
| Time | Source | Event |
|---|---|---|
| 01:08:47.401 | webview → exthost | User prompt submitted (io_message) |
| 01:08:50.681 | claude.exe (SDK) | Stream started - received first chunk |
| 01:09:05.687 | claude.exe (SDK) | [WARN] [Stall] stream_idle_partial lastChunkAgeMs=15007 bytesTotal=658 idleDeadlineMs=300000 |
| 01:09:20.713 | webview → exthost | sdk_stream_ended_no_result with had_error: true, message_count: 198 |
| 01:09:20.714 | webview | update_session_state → idle |
| 01:09:34.089 | claude.exe (SDK) | [WARN] [Stall] stream_idle_partial lastChunkAgeMs=15009 bytesTotal=694 — byte count grew (658 → 694), SDK still receiving |
| 01:09:44.279 | claude.exe (SDK) | [WARN] Streaming stall detected: 53.6s gap between events (stall #1) |
| 01:10:07.329 | session JSONL | First assistant message finalized (full markdown response, ~6KB) |
| 01:10:15.667 | session JSONL | Second assistant message finalized: tool_use AskUserQuestion (well-formed, 4 options) |
| 01:10:15.669 | claude.exe (SDK) | [DEBUG] executePermissionRequestHooks called for tool: AskUserQuestion |
| 01:10:15 | webview UI | "Unhandled case: [object Object]" toast appears |
| 01:10:15.753 | claude.exe (SDK) | [WARN] Streaming completed with 1 stall(s), total stall time: 53.6s |
The disagreement
The webview and SDK report incompatible conclusions about the same stream:
- SDK side: Stream completed successfully, 1 stall (53.6s gap),
idleDeadlineMs=300000(5 min). Two assistant messages persisted to JSONL. Final permission hook fired normally. - Webview side: Stream ended with error at 01:09:20 — only ~30s after the previous chunk and 15s after the first partial-stall warning. Session state set to
idle. Subsequent SDK events (the permission hook arriving 55s later) are unhandled.
The SDK's tolerance (idleDeadlineMs=300000) is two orders of magnitude longer than what the webview seems to be using. With long inter-chunk pauses being normal for heavy reasoning turns (243k token cache read + multi-section markdown response), the webview's effective threshold falsely declares failure mid-response.
Reproduction
Not reliably reproduced yet. Conditions present in this incident:
- Resumed session with substantial prior context (cache_read 243,612 tokens)
- Complex reasoning turn (forensic kernel-dump analysis, 4-option
AskUserQuestionending) - A 53s gap between streaming events mid-response
- Earlier in the same session: previous
AskUserQuestionhad been denied withinterrupt: true(~4m53s deliberation). Unclear if the prior interrupted state contributes.
I suspect the trigger is "any long inter-chunk gap during streaming" but cannot confirm from a single occurrence.
What I'd hope for
- Webview stall-tolerance review: should match the SDK's
idleDeadlineMs(or coordinate with the SDK via an explicit "still alive" signal) rather than independently declaring failure. - Renderer state machine: add a graceful path for "SDK event arrives after I declared the stream dead" — recover or at least surface a clearer error than
Unhandled case: [object Object]. - Logging guidance: the renderer error stack is only available in the Dev Tools console with "Preserve log" pre-enabled. Could the extension forward unhandled renderer errors to the output channel so they're captured by default?
Local logs available
Happy to share on request:
- VSC output channel save:
D:\tmp\cc-output-2026-05-15.log(1407 lines, full session) - Session JSONL:
~/.claude/projects/D--UF-LP-OneDrive-Claude-Work/33a841f2-0f2a-489c-87ff-a9dcf24606a5.jsonl(4.4 MB) - Dev Tools console snapshot: incomplete — Dev Tools was opened after the event with "Preserve log" off, so the actual stack trace for the toast was not captured. Will capture on recurrence.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗