[BUG] VSCode: deserializeWebviewPanel ignores saved sessionId — tabs show wrong conversation content after restart

Resolved 💬 2 comments Opened Mar 16, 2026 by voyagi Closed Apr 14, 2026

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

  1. Open VS Code with the Claude Code extension
  2. Open 3+ conversation tabs (e.g., by pasting different URLs as prompts)
  3. Each tab has a distinct conversation with unique content
  4. Close and reopen VS Code (or reload the window)
  5. 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

View original on GitHub ↗

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