claude-code - 💡(How to fix) Fix VSCode extension v2.1.141: "Unhandled case: [object Object]" banner from assertNever on unknown streaming-event types [3 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#58897Fetched 2026-05-14 03:36:40
View on GitHub
Comments
3
Participants
3
Timeline
10
Reactions
0
Author
Timeline (top)
commented ×3labeled ×3cross-referenced ×2subscribed ×2

webview/index.js in the VSCode extension has a TypeScript assertNever-style exhaustive-check (helper QB1) over Anthropic streaming-event types. When the server emits an event type the switch doesn't cover, the helper throws Error(\Unhandled case: ${J}`)interpolating the **whole** event object instead of its.type` field — producing the user-visible banner text:

Unhandled case: [object Object]
View output logs · Troubleshooting resources

The banner is non-dismissable except via the manual ×, persists across subsequent tool calls, and is alarming to operators who reasonably assume the session is broken. The underlying session and the model are unaffected — it's a renderer-side throw, not a data-flow problem.

Error Message

webview/index.js in the VSCode extension has a TypeScript assertNever-style exhaustive-check (helper QB1) over Anthropic streaming-event types. When the server emits an event type the switch doesn't cover, the helper throws Error(\Unhandled case: ${J}`)interpolating the **whole** event object instead of its.typefield — producing the user-visible banner text: function QB1($, Z) { throw Error(Z ??Unhandled case: ${$}`) }

  • error — server-side error events 1. Format the error usefully (1-line change): throw Error(Z ?? Unhandled case: ${$?.type ?? JSON.stringify($)})

Root Cause

In a prior internal investigation we briefly hypothesized that the banner was triggered by the harness's <persisted-output> wrapper (the marker shown when a tool result is spilled to disk because it exceeds the inline display cap). That hypothesis was falsified: the string persisted-output does not appear anywhere in the extension bundle — the wrapper is harness-side text the extension just renders as a string, and is unrelated to the streaming-event switch.

Code Example

Unhandled case: [object Object]
View output logs · Troubleshooting resources

---

// Helper (assertNever pattern, emitted by bundler)
function QB1($, Z) { throw Error(Z ?? `Unhandled case: ${$}`) }

// Caller — switch over streaming-event types
switch (J.type) {
  case "signature_delta":   { /* ... */ break }
  case "compaction_delta":  break
  // ...other cases...
  default: QB1(J)   // ← passes whole event object, not J.type
}

---

function QB1($, Z) {
  throw Error(Z ?? `Unhandled case: ${$?.type ?? JSON.stringify($)}`)
}

---

# Confirm extension version
ls ~/.vscode/extensions/ | grep claude-code

# Find the throwing helper
grep -n "Unhandled case" ~/.vscode/extensions/anthropic.claude-code-2.1.141-*/webview/index.js

# Enumerate the switch's known cases
python3 -c "
import re
data = open('$HOME/.vscode/extensions/anthropic.claude-code-2.1.141-darwin-arm64/webview/index.js').read()
m = re.search(r'Unhandled case', data)
chunk = data[max(0, m.start()-3000):m.start()]
print(sorted(set(re.findall(r'case\"([^\"]+)\"', chunk))))
"
RAW_BUFFERClick to expand / collapse

Summary

webview/index.js in the VSCode extension has a TypeScript assertNever-style exhaustive-check (helper QB1) over Anthropic streaming-event types. When the server emits an event type the switch doesn't cover, the helper throws Error(\Unhandled case: ${J}`)interpolating the **whole** event object instead of its.type` field — producing the user-visible banner text:

Unhandled case: [object Object]
View output logs · Troubleshooting resources

The banner is non-dismissable except via the manual ×, persists across subsequent tool calls, and is alarming to operators who reasonably assume the session is broken. The underlying session and the model are unaffected — it's a renderer-side throw, not a data-flow problem.

Environment

  • Extension: anthropic.claude-code v2.1.141
  • Platform: darwin-arm64 (macOS)
  • Bundle path: ~/.vscode/extensions/anthropic.claude-code-2.1.141-darwin-arm64/webview/index.js

Source of the throw

// Helper (assertNever pattern, emitted by bundler)
function QB1($, Z) { throw Error(Z ?? `Unhandled case: ${$}`) }

// Caller — switch over streaming-event types
switch (J.type) {
  case "signature_delta":   { /* ... */ break }
  case "compaction_delta":  break
  // ...other cases...
  default: QB1(J)   // ← passes whole event object, not J.type
}

The template-string interpolation ${$} calls .toString() on the event object, yielding the literal "[object Object]".

Known-handled cases in v2.1.141

Extracted from the bundle (last ~3 KB before the Unhandled case literal):

text, text_delta, thinking_delta, signature_delta, citations_delta, input_json_delta, compaction_delta, content_block_start, content_block_delta, content_block_stop, message_start, message_delta, message_stop.

Likely missing cases

  • ping — Anthropic streaming keepalive event
  • error — server-side error events
  • Any new content-block-delta type shipped after the v2.1.141 build cutover

A real reproduction of the offending event requires capturing the VSCode extension output log at the moment of the throw — I have not done that here. The diagnosis is grounded in static source inspection.

Suggested fixes

1. Format the error usefully (1-line change):

function QB1($, Z) {
  throw Error(Z ?? `Unhandled case: ${$?.type ?? JSON.stringify($)}`)
}

Operators would then see e.g. Unhandled case: ping instead of Unhandled case: [object Object], making the bug self-reporting.

2. Soften the failure mode (recommended in addition to #1):

Streaming events the renderer doesn't recognize should be logged to the output channel and skipped, not thrown as a top-of-window banner. Hard-throwing on every new server-side event type couples extension stability to backend compatibility — every Anthropic API addition risks a banner storm in older extension versions still in the field.

Repro

The banner fires intermittently during long-running sessions with many streaming responses. I have not produced a deterministic repro (would need to inject a streaming event of an unknown type).

Diagnosis trail (for reproducibility)

# Confirm extension version
ls ~/.vscode/extensions/ | grep claude-code

# Find the throwing helper
grep -n "Unhandled case" ~/.vscode/extensions/anthropic.claude-code-2.1.141-*/webview/index.js

# Enumerate the switch's known cases
python3 -c "
import re
data = open('$HOME/.vscode/extensions/anthropic.claude-code-2.1.141-darwin-arm64/webview/index.js').read()
m = re.search(r'Unhandled case', data)
chunk = data[max(0, m.start()-3000):m.start()]
print(sorted(set(re.findall(r'case\"([^\"]+)\"', chunk))))
"

Note on a red herring

In a prior internal investigation we briefly hypothesized that the banner was triggered by the harness's <persisted-output> wrapper (the marker shown when a tool result is spilled to disk because it exceeds the inline display cap). That hypothesis was falsified: the string persisted-output does not appear anywhere in the extension bundle — the wrapper is harness-side text the extension just renders as a string, and is unrelated to the streaming-event switch.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix VSCode extension v2.1.141: "Unhandled case: [object Object]" banner from assertNever on unknown streaming-event types [3 comments, 3 participants]