Skip to content

fix(vscode): stop config update loop from flooding SSE and killing server - #7172

Merged
markijbema merged 2 commits into
mainfrom
mark/fix-global-config-dispose-all
Mar 17, 2026
Merged

fix(vscode): stop config update loop from flooding SSE and killing server#7172
markijbema merged 2 commits into
mainfrom
mark/fix-global-config-dispose-all

Conversation

@markijbema

@markijbema markijbema commented Mar 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Two fixes for the settings panel flooding the server with events and killing it:

  1. Stop Instance.disposeAll() from being called on every global config update. Previously, Config.updateGlobal() would nuke all running CLI instances (destroying session state, MCP connections, and in-flight operations across every project) whenever any global config changed. The global.reset() call already clears the config cache so consumers pick up the new config on their next read. The disposeAll() was unnecessary overkill.

  2. Break infinite loop caused by Kobalte Select firing onChange on options list changes. Kobalte's Select has an internal createEffect that re-filters selected keys whenever flattenOptionKeys changes. When a global.disposed or server.instance.disposed SSE event arrives, the extension re-fetches config and pushes configLoaded to the webview. Solid creates new array references for the options, Kobalte detects the change, fires onChange with the same value, which calls updateConfig → PATCH /global/config → emits global.disposed → loop. With allowDuplicateSelectionEvents: true (Kobalte's default), this fires even when the value hasn't changed.

The loop

configLoaded → setConfig() → new options array ref
  → Kobalte Select internal effect fires onChange
  → onSelect → updateConfig({ default_agent: ... })
  → PATCH /global/config → Config.updateGlobal()
  → global.disposed event via SSE
  → reloadAfterAuthChange() → fetchAndSendConfig()
  → configLoaded → repeat ×N KiloProvider instances

Fix

  • Remove Instance.disposeAll() from updateGlobal() (separate correctness fix — this was collateral damage on each loop iteration, not the cause)
  • Guard all three settings Select onSelect handlers to skip updateConfig when the new value equals the current config value, breaking the loop

Config.updateGlobal() was calling Instance.disposeAll() on every config
change, which destroyed all session state, MCP connections, and in-flight
operations across every project. This meant that any config change (e.g.
removing a mode in VS Code) would effectively kill all running CLI
instances.

The global.reset() call already clears the config cache so consumers
will pick up the new config on their next read. The disposeAll() was
unnecessary overkill.
@markijbema
markijbema force-pushed the mark/fix-global-config-dispose-all branch from b004c16 to 13ff40c Compare March 17, 2026 11:22
Kobalte's Select fires onChange when the options list changes (even if
the selected value is the same), which triggers updateConfig → PATCH
/global/config → global.disposed → configLoaded → new options array →
onChange again, creating an infinite loop that floods SSE with events
and kills the server.

Add guards to all three settings Select components to skip updateConfig
when the new value equals the current config value.
@markijbema markijbema changed the title fix: don't dispose all instances on global config update fix(vscode): stop config update loop from flooding SSE and killing server Mar 17, 2026
@markijbema
markijbema marked this pull request as ready for review March 17, 2026 11:59
// in-flight operations across every project whenever any global config changed
// (e.g. removing a mode). The cache reset above is sufficient — consumers will
// pick up the new config on their next read.
GlobalBus.emit("event", {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Existing instances keep using the old global config

global.reset() only invalidates the lazy result from Config.global(). Every open project still has its merged config cached in Config.state() via Instance.state(), so removing Instance.disposeAll() means active sessions keep stale modes, providers, and other global settings until that instance is explicitly disposed or the server restarts.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@markijbema true?

@kilo-code-bot

kilo-code-bot Bot commented Mar 17, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0

Fix these issues in Kilo Cloud

Issue Details (click to expand)

WARNING

File Line Issue
packages/opencode/src/config/config.ts 1561 Removing Instance.disposeAll() leaves each project's cached Config.state() stale after a global config change.
Other Observations (not in diff)

No additional issues found outside the diff.

Files Reviewed (4 files)
  • packages/kilo-vscode/webview-ui/src/components/settings/AgentBehaviourTab.tsx - 0 issues
  • packages/kilo-vscode/webview-ui/src/components/settings/DisplayTab.tsx - 0 issues
  • packages/kilo-vscode/webview-ui/src/components/settings/ExperimentalTab.tsx - 0 issues
  • packages/opencode/src/config/config.ts - 1 issue

Reviewed by gpt-5.4-20260305 · 491,849 tokens

@markijbema
markijbema merged commit f1d10f8 into main Mar 17, 2026
16 checks passed
@markijbema
markijbema deleted the mark/fix-global-config-dispose-all branch March 17, 2026 12:32
jliounis pushed a commit to jliounis/kilocode that referenced this pull request May 18, 2026
…-dispose-all

fix(vscode): stop config update loop from flooding SSE and killing server
t7tran pushed a commit to t7tran/kilocode that referenced this pull request Aug 14, 2026
…-dispose-all

fix(vscode): stop config update loop from flooding SSE and killing server
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants