[BUG] VSCode: deserializeWebviewPanel ignores saved sessionId — tabs show wrong conversation content after restart
Description
After restarting or reloading VS Code, editor tabs that previously had active Claude Code conversations restore with wrong conversation content — showing a different conversation than what was originally in that tab. In some cases, multiple tabs all show the same (wrong) conversation.
Steps to Reproduce
- Open VS Code with the Claude Code extension
- Open 3+ conversation tabs (e.g., by pasting different URLs as prompts)
- Each tab has a distinct conversation with unique content
- Close and reopen VS Code (or reload the window)
- The tabs are restored, but their content is from other conversations or they show blank/new sessions
Expected Behavior
Each restored tab should show the same conversation it had before the restart.
Actual Behavior
Tabs show content from a different conversation, or all tabs show the same conversation. The original conversation data is not lost — JSONL files exist on disk and appear in conversation history — but the tab-to-session binding is broken on restore.
Root Cause (from extension source analysis)
The bug is in the WebviewPanelSerializer registered for claudeVSCodePanel. In extension.js (v2.1.76), the deserialization handler:
registerWebviewPanelSerializer("claudeVSCodePanel", {
async deserializeWebviewPanel(panel, state) {
// state contains the saved sessionId, but it's IGNORED
let isFullEditor;
if (typeof state?.isFullEditor === "boolean")
isFullEditor = state.isFullEditor;
else
isFullEditor = window.tabGroups.all.findIndex(
(g) => g.viewColumn === panel.viewColumn
) === 0;
provider.setupPanel(panel, void 0, void 0, isFullEditor)
// ^^^^^^^^ ^^^^^^^^
// prompt sessionId
// Both hardcoded to undefined!
}
})
The state parameter (second argument) contains the sessionId that VS Code saved before shutdown, but only isFullEditor is extracted from it. The sessionId is never passed to setupPanel.
Compare with how panels are created (same file), where the session ID is properly passed:
// claude-vscode.editor.open command — works correctly:
commands.registerCommand("claude-vscode.editor.open", async (sessionId, prompt, viewColumn) => {
provider.createPanel(sessionId, prompt, viewColumn)
})
Suggested Fix
Pass the session ID from the saved state to setupPanel:
// Before (broken):
provider.setupPanel(panel, void 0, void 0, isFullEditor)
// After (fixed):
provider.setupPanel(panel, state?.initialPrompt, state?.sessionId, isFullEditor)
This requires that setState() in the webview also saves sessionId (needs verification — the webview's getState()/setState() calls should include the session ID in the persisted state object).
Related Issues
- #24172 — Conversations disappear when closing VSCode
- #29017 — Conversation history lost in VSCode extension
- #15330 — Chat session not persisted after Reload Window
- #9258 — History sessions lost in VSCode plugin
- #27339 — Forked conversations disappear when resuming
These likely share the same root cause or are symptoms of this deserialization bug.
Environment
- VS Code Extension: Claude Code v2.1.76 (win32-x64)
- OS: Windows 10 (MSYS2/Git Bash)
- Platform: VS Code desktop
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗