VS Code extension: thread list is fetched once per webview mount and never refreshes

Open 💬 0 comments Opened Jul 30, 2026 by liuclare

What version of the IDE extension are you using?

26.721.41059 (bundled app-server 0.146.0-alpha.3.1)

What subscription do you have?

Plus

Which IDE are you using?

VS Code 1.122.1

What platform is your computer?

Linux 7.0.0-27-generic x86_64 unknown

What issue are you seeing?

The sidebar's thread list is populated by a single thread/list call when the webview mounts, and nothing in the UI ever triggers another one. Threads created or updated outside that window (CLI, another VS Code window, MCP clients) never appear until the window is reloaded.

The webview is created with retainContextWhenHidden: true, so hiding and re-showing the sidebar does not remount it and does not refetch.

Traced at the app-server stdio boundary, one window:

window start   thread/list  id=codex.chatSessionProvider:0
sidebar mount  thread/list  id=CodexWebviewProvider.webview:<uuid>
(clicking the history/clock button, opening "View all", hiding and re-showing the
 secondary sidebar: no further requests)
Developer: Reload Webviews  thread/list  id=CodexWebviewProvider.webview:<new uuid>

That leaves a new window, Reload Window, or Developer: Reload Webviews as the only ways to refresh, and the last one reloads every webview in the window, including those of unrelated extensions.

What steps can reproduce the bug?

  1. Open the Codex sidebar in VS Code and let the thread list load.
  2. In a terminal, start a new session in the same CODEX_HOME: codex "hello", or create one from another VS Code window.
  3. Back in the first window, click the history (clock) button and "View all". The new thread is not listed, and no thread/list request is issued.
  4. Hide and re-show the sidebar: still no request.
  5. Run Developer: Reload Webviews (or reload the window): the list is now current.

What is the expected behavior?

The thread list should refresh when the user interacts with it: at minimum when the history popover or "View all" is opened, or through an explicit refresh control in the view title bar.

Polling is not required, and would run into the cost concern raised in #22411. An interaction-triggered refresh is cheap on 0.146.0: with useStateDbOnly: true a thread/list (limit 50) returns in about 20 ms and, under strace, opens no rollout files — it is served from state_5.sqlite. The same held with useStateDbOnly: false, on a profile whose state DB is fully backfilled.

Additional information

Related, all on the app side rather than the extension: #21974 (app should live-refresh CLI-created sessions), #26947 (add a refresh/reload button, Windows app), #11907 (manual refresh or auto-sync for cross-surface conversations), #33859 (same class of problem, scoped to the background-agent panel). I did not find one for the extension's thread list.

The existing refresh path is sufficient: patching the webview bundle so that a throttled click handler calls refreshRecentConversations({mode: 'expanded'}) makes the list current on every click, issues one thread/list per interaction, and produces no requests while idle.

---

Investigation and draft by Claude Code (Claude Opus 5), reviewed and filed by @liuclare.

View original on GitHub ↗