[BUG] VS Code extension: input text lost when new session initializes due to listSessions race condition

Resolved 💬 3 comments Opened Mar 1, 2026 by yoheidemachi Closed Mar 4, 2026

Description

When opening a new chat session in the VS Code extension, if the user starts typing in the input field immediately, the typed text is silently cleared after a few seconds. This happens because the webview re-renders the input component when listSessions() completes asynchronously, unmounting and remounting the input component and losing all typed text.

Steps to Reproduce

  1. Open VS Code with the Claude Code extension
  2. Open a new Claude Code chat panel (no previous session to restore)
  3. Immediately start typing a message in the input field (do not submit)
  4. Wait 2-5 seconds
  5. Observe: the input text disappears and the session appears to "reset"

Expected Behavior

Typed text in the input field should be preserved across internal re-renders and session state changes.

Actual Behavior

The input text is silently cleared after a few seconds, forcing the user to retype their message.

Root Cause Analysis

After analyzing the bundled source code (extension.js and webview/index.js), the issue is a race condition between user input and asynchronous session list loading:

Sequence of events:

  1. Webview boots (fT1() in webview/index.js):
  • If no previous session ID exists, createSession({ isExplicit: false }) is called immediately (line ~244986), creating an empty session with a unique internalId (via crypto.randomUUID())
  • Simultaneously, listSessions() is called (line ~244961), which is async
  1. User starts typing into the input field (Ln0 component, line ~236261)
  • Input text is stored only in React useState("") (line ~236280) and DOM textContent
  • No persistence to localStorage or VSCode webview state
  1. listSessions() completes (after a few seconds):
  • doListSessions() (line ~166845) processes server-side sessions
  • If Y (sessions changed) is true and URL contains a session parameter (line ~166886-166889):

``js
let U = new URLSearchParams(window.location.search).get("session");
if (U) {
let z = G.find(V => V.sessionId.value === U);
if (z) this.activeSession.value = z; // activeSession reassigned!
}
``

  • Even without a URL session parameter, this.sessions.value = G (line ~166885) triggers reactive effects
  1. activeSession changes → the session view component (uo0) is keyed by activeSession.value.internalId (line ~244350):

``jsx
key: activeSession.value.internalId
`
A different
internalId means React **unmounts the entire component tree** (including Ln0`) and remounts it fresh

  1. Input text is lost because useState("") resets to empty string on remount

Why there's no recovery:

The input component (Ln0) has no persistence layer:

  • No saving to localStorage
  • No saving to VSCode webview state (acquireVsCodeApi().setState())
  • No debounced backup of input text
  • The _q0 state manager (line ~244921) only persists sessionID and sessionUpdatedAt, not input text

Suggested Fix

Any of these approaches (or a combination) would fix the issue:

Option A: Persist input buffer in webview state (simplest)

In the Ln0 component, save input text to VSCode webview state on every change and restore on mount:

// On input change
vscodeApi.setState({ ...state, inputBuffer: text });

// On mount
const savedInput = vscodeApi.getState()?.inputBuffer || "";

Option B: Prevent unnecessary activeSession reassignment

In doListSessions(), skip reassigning activeSession if the current session has no sessionId (meaning the user hasn't submitted yet and is still in the input phase):

// Before reassigning activeSession, check if user might be typing
if (this.activeSession.value && !this.activeSession.value.sessionId.value 
    && !this.activeSession.value.busy.value) {
  // Don't reassign - user is in a fresh session, possibly typing
  return;
}

Option C: Transfer input text across session switches

When activeSession changes, capture the input text from the old session's component and inject it into the new session's component via a shared ref or context.

Environment

  • OS: macOS (Darwin 25.3.0, Apple Silicon)
  • VS Code: Latest stable
  • Claude Code Extension: v2.1.63
  • Platform: darwin-arm64

View original on GitHub ↗

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