VSC: webview declares "sdk_stream_ended_no_result had_error" prematurely during long inter-chunk gaps; orphaned AskUserQuestion then triggers "Unhandled case: [object Object]"

Resolved 💬 2 comments Opened May 15, 2026 by Tjeef Closed May 15, 2026

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.exe at …\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_stateidle |
| 01:09:34.089 | claude.exe (SDK) | [WARN] [Stall] stream_idle_partial lastChunkAgeMs=15009 bytesTotal=694byte 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 AskUserQuestion ending)
  • A 53s gap between streaming events mid-response
  • Earlier in the same session: previous AskUserQuestion had been denied with interrupt: 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

  1. 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.
  2. 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].
  3. 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.

View original on GitHub ↗

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