Skip to content

UI shows "Unhandled case: [object Object]" toast when SDK stream ends with error after stall #59054

Closed as duplicate

Description

@physppcf-png

Summary

When the streaming connection to the API stalls and the SDK gives up with had_error: true, the Claude Code VS Code extension's webview shows a generic toast reading Unhandled case: [object Object] instead of a user-meaningful message. The error object is passed straight into a default switch case and serialized via implicit String(), producing [object Object].

This blocks the visible stream — from the user's perspective, Claude has stopped working, and they have to dismiss the toast (or reload the webview with Cmd+R) before the next interaction.

Environment

  • OS: macOS 15 (Darwin 25.3.0), Apple Silicon
  • VS Code: stable (latest)
  • Claude Code extension: 2.1.141 (latest available, no update offered)
  • Native binary: `claude` 2.1.141 from extension bundle
  • Plan: standard (fast mode unavailable: extra usage billing)

Repro steps

  1. Open Claude Code in VS Code, start any session
  2. Wait for a moment when the network/API streaming stalls (occurs intermittently, multiple times per hour in our environment — exact trigger unknown, possibly correlated with API load or local network jitter)
  3. Observe: stream goes silent for 15+ seconds while you're awaiting a response
  4. Observe: SDK eventually emits `sdk_stream_ended_no_result` with `had_error: true`
  5. Observe the bug: an orange toast appears reading `Unhandled case: [object Object]` with links "View output logs" and "Troubleshooting resources"

Expected behavior

The toast should display a meaningful, user-facing message such as:

  • "Connection stalled — retry?" (with retry button)
  • "Stream ended unexpectedly — your message may be incomplete"
  • Anything except a serialized object placeholder

Actual behavior

Toast displays the literal string `Unhandled case: [object Object]`. No actionable information. User must dismiss the toast and either retry the request or reload the webview (`Cmd+R` while panel has focus) to continue.

Log evidence

From `~/Library/Application Support/Code/logs/.../Anthropic.claude-code/Claude VSCode.log`:

```
2026-05-14T11:58:04.535Z [WARN] [Stall] stream_idle_partial lastChunkAgeMs=15000 bytesTotal=656 idleDeadlineMs=300000
2026-05-14T11:58:19.551 webview event log_event sdk_stream_ended_no_result {had_error: true, subagent_count: 0, message_count: 74}
2026-05-14T11:58:24.785 [WARN] Streaming stall detected: 35.2s gap between events (stall #1)
2026-05-14T11:59:19.105 [WARN] Streaming completed with 1 stall(s), total stall time: 35.2s
```

Searching the standard log files (`Claude VSCode.log`, `renderer.log`, `exthost.log`) for `unhandled` or `object Object` returns zero matches — the toast text is rendered only in the webview and is not captured in the extension's host logs. This makes self-diagnosis hard for affected users.

Other recurring errors in the same session that may share the same UI default-case path:

```
[ERROR] MCP server "claude-vscode" Failed to fetch tools: MCP error -32601: Method not found
[ERROR] MCP server "claude.ai Netlify" Connection failed: Cloudflare 502 Bad gateway
[ERROR] MCP server "claude.ai Goodnotes" Anthropic Proxy: Invalid content from server
```

Suggested fix

In the webview's error-handling switch, replace the default branch:

```ts
default:
showToast(`Unhandled case: ${error}`); // implicit String(error) → "[object Object]"
```

with something like:

```ts
default:
console.error('Unhandled error case', error);
const message = error?.message ?? error?.error?.message ?? 'Unknown error';
showToast(`Stream interrupted: ${message}`, { action: 'Retry' });
```

That's a few-line change and immediately makes the failure mode actionable.

Impact

  • Blocks user-visible stream rendering on every stall
  • Users perceive the assistant as unresponsive even though the SDK is recoverable
  • The toast text gives zero diagnostic information; "View output logs" opens a log channel that doesn't contain the toast text either

Activity

  1. github-actions commented on May 14, 2026

    @github-actions

    Found 3 possible duplicate issues:

    1. Unhandled case: [object Object] on stream end with had_error: true after long sessions #59013
    2. [Bug] VSCode extension crashes on unknown Anthropic SSE event type — "Unhandled case: [object Object]" #59022
    3. VSCode extension v2.1.141: "Unhandled case: [object Object]" banner from assertNever on unknown streaming-event types #58897

    This issue will be automatically closed as a duplicate in 3 days.

    • If your issue is a duplicate, please close it and 👍 the existing issue instead
    • To prevent auto-closure, add a comment or 👎 this comment

    🤖 Generated with Claude Code

  2. sigma512 commented on May 14, 2026

    @sigma512

    Independent repro on the same build (cc_version=2.1.141.bb8, macOS 15 / Darwin 25.3.0, VS Code stable). Confirming the failure mode in this issue exactly, and adding two observations:

    1. Same sequence in the host log:

    07:19:08.007 [DEBUG] Stream started - received first chunk
    07:19:23.005 [WARN] [Stall] stream_idle_partial lastChunkAgeMs=15001 bytesTotal=745 idleDeadlineMs=300000
    07:19:38.022 webview log_event sdk_stream_ended_no_result {had_error: true, subagent_count: 0, message_count: 354}
    07:19:45.522 [WARN] Streaming stall detected: 37.5s gap between events (stall #1)
    07:19:54.285 [WARN] Streaming completed with 1 stall(s), total stall time: 37.5s
    

    After the toast, session state transitioned to idle and the panel stopped rendering further output, matching the OP description (dismiss toast or Cmd+R reload to continue).

    2. Frequency: in a single morning across four VS Code windows on one machine, I see sdk_stream_ended_no_result had_error:true events in windows 2, 3, and 4. The bb8 / 926 cc_version values alternate in the same log (looks like a rolling build/canary swap), and stalls appear on both. Stalls are typically ~15s of lastChunkAgeMs before the SDK gives up, well under the 300s idleDeadlineMs — so the SDK's own stall detector is firing aggressively and the webview's default error-case is what users actually see.

    The suggested fix in the OP (extract error?.message ?? error?.error?.message) is the right shape, but the deeper fix is probably also surfacing a retry affordance on the toast — right now the only recovery is to retype the last message, which loses any in-flight tool calls.

  3. physppcf-png commented on May 14, 2026

    @physppcf-png
    Author

    Thanks @sigma512 for the independent repro and the additional observations. Two things worth highlighting that came out of your data:

    1. The SDK stall detector is the actual root cause, not network jitter.

    Your observation that stalls fire at ~15s lastChunkAgeMs while idleDeadlineMs is 300s is the most important finding here. The SDK is giving up roughly 20x earlier than its own configured deadline. From the user's perspective the connection looks fine (other API calls succeed in parallel), but the SDK has already emitted sdk_stream_ended_no_result with had_error: true. So the fix sequence is probably:

    1. Fix the early-bail. Either honor idleDeadlineMs end-to-end, or expose a separate streamIdleWarnMs and only error out at the deadline. As things stand, every brief network hiccup is treated as a fatal stream end.
    2. Fix the UI default-case (per the OP) so when an error does propagate, users see something actionable.

    If only (2) gets done, users will get nicer toasts but still lose mid-task output multiple times per session. Both fixes together are needed.

    2. Retry affordance: agreed, and worth being explicit.

    Right now the only recovery is to retype the last message, which loses any in-flight tool calls. A retry button on the toast would need to:

    • Resume the failed stream if the SDK supports it, or
    • Re-issue the last user message with the partial assistant turn marked so the model knows to continue rather than restart, or at minimum
    • Re-issue the last user message and warn the user that tool calls from the interrupted turn will not be replayed

    Even just the third option (cleanest semantics, no SDK changes) would be a major UX improvement over the current state.

    Frequency match for me too: hitting this multiple times in a single working session, across both bb8 and earlier builds.

  4. romankanevsky commented on May 14, 2026

    @romankanevsky

    Confirming this on Windows + VS Code Remote-SSH (laptop -> Linux VM via vscode-server). Same trigger pattern, same outcome, plus one extra symptom not captured in the OP.

    Environment

    • Host: Windows 11 (Azure AD Joined laptop), VS Code Remote-SSH into a Linux VM
    • Extension on remote: anthropic.claude-code-2.1.140 (auto-resumed via launch_claude --resume)
    • Native binary on VM: /home/<user>/.vscode-server/extensions/anthropic.claude-code-2.1.140/resources/native-binary/claude
    • Model: claude-opus-4-7 (1M context, API Usage Billing)
    • Network path: laptop -> corporate Prisma Access / Zscaler -> api.anthropic.com
    • Local skill invocation with ~4 KB prompt, 10+ tool calls (Bash + Read), ~5.6 KB final assistant text

    Stall signature

    From Claude VSCode.log (extension log on vscode-server, UTC):

    2026-05-14T13:25:30.506Z [DEBUG] Stream started - received first chunk
    2026-05-14T13:26:03.795Z [WARN] [Stall] stream_idle_partial lastChunkAgeMs=15001 bytesTotal=655 idleDeadlineMs=300000
    2026-05-14T13:26:29.797Z [WARN] [Stall] stream_idle_partial lastChunkAgeMs=14999 bytesTotal=691 idleDeadlineMs=300000
    2026-05-14T13:26:44.798Z [WARN] [Stall] stream_idle_partial lastChunkAgeMs=30001 bytesTotal=691 idleDeadlineMs=300000
    2026-05-14T13:27:01.638Z [WARN] [Stall] stream_idle_partial lastChunkAgeMs=15001 bytesTotal=727 idleDeadlineMs=300000
    2026-05-14T13:27:03.288Z [WARN] Streaming stall detected: 74.5s gap between events (stall #1)
    2026-05-14T13:27:10.908Z [WARN] Streaming completed with 1 stall(s), total stall time: 74.5s
    2026-05-14T13:27:29.784Z [WARN] [Stall] stream_idle_partial lastChunkAgeMs=14999 bytesTotal=648 idleDeadlineMs=300000
    2026-05-14T13:27:50.936Z [WARN] Streaming stall detected: 36.2s gap between events (stall #1)
    

    Two stalls in the same turn, 74.5 s and 36.2 s, matching the gap profile in the OP.

    CLI continues, GUI does not

    Session JSONL on disk (~/.claude/projects/.../<session-uuid>.jsonl) has the full ~5.6 KB final assistant text written at T13:28:54Z. CLI claude --resume <sessionId> opens the same session and renders it fully. VS Code webview shows the chat truncated right after the user prompt; no Unhandled case toast was visible to the user, but the rendering pipeline behaved exactly as #58984 describes: backend kept producing, panel did not update.

    Reload Window does NOT recover the response

    This is the divergence from #58984 ("reloading re-renders the full conversation from disk"). On this session, Developer: Reload Window re-spawned claude --resume (logged twice at T13:30:19Z and T13:31:12Z) but the truncated render persisted across both reloads. The chat in GUI still ends at the user prompt; subsequent shorter assistant turns in the same session DO render in GUI.

    Structural observation in the session JSONL: the assistant entry that fails to render has attributionSkill: "<skill-name>" set (because the turn was inside a slash-skill invocation). Subsequent turns outside the skill scope omit this field and render fine. Not proven causal, but the only structural difference between the missing entry and the visible entries in the same session JSONL. Worth checking whether the webview branch that handles attributionSkill-tagged messages is the missing renderer case (cf. #55863 pattern: extension.js recognizes message subtype, enqueues onto inputStream, webview has no render branch).

    Adjacent hook validation failure (probably unrelated, mentioning for completeness)

    Stop hook returning hookSpecificOutput.additionalContext got rejected by schema at the exact second the missing assistant turn completed:

    2026-05-14T13:28:54.866Z [DEBUG] Hook JSON output validation failed - (root): Invalid input
    Expected schema (Stop event): { continue, suppressOutput, stopReason, decision, reason, systemMessage, permissionDecision }
    hookSpecificOutput.{additionalContext} is only valid for UserPromptSubmit / PostToolUse / PostToolBatch / PreToolUse
    

    The hook write was a no-op (Stop hook output is informational only), so this is unlikely to be the render trigger, but the timing collision is interesting if the same code path that surfaces hook output to the webview also dispatches the assistant render event.

    Workaround

    For long-running, multi-tool-call turns that historically hit stalls (e.g. ticket-triage skills with 10+ Read/Bash/Grep calls and 4-6 KB final output), CLI is the reliable surface; GUI loses the final assistant text whenever a stall lands in the wrong place. The Windows + corporate proxy network path makes stalls more frequent than the macOS profile in the OP (39 separate Streaming stall detected events in one workday, peak gap 131.5 s).

    Happy to attach the full JSONL + extension log for the affected session privately if useful.

  5. atrwallace commented on May 14, 2026

    @atrwallace

    Same issue on Windows 11, VS Code 1.119.1 (rolled back from 1.120, same bug), extension 2.1.141, Opus 4.7. Stream stalls + Unhandled case toast.

  6. claude commented on May 15, 2026

    @claude
    Contributor

    This is a duplicate of #58897, which was fixed as of version 2.1.142.

  7. github-actions commented on Jul 4, 2026

    @github-actions

    This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.

  8. locked as resolved and limited conversation to collaborators on Jul 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:idebugSomething isn't workingplatform:macosIssue specifically occurs on macOSplatform:vscodeIssue specifically occurs in VS Code

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions