You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG] Desktop v1.18.1: file:// plugin persists in UI after removal from all config sources #37099
After removing a \ile:///D:/plugins/bug-compaction.ts\ plugin from all known config sources and restarting OpenCode Desktop, the plugin still appears in the Desktop UI plugin list and generates \Failed to load plugin\ errors on every startup.
From packages/opencode/src/config/config.ts (Desktop app.asar decompiled, v1.18.1):
plugin_origins is derived state
typeInfo=ConfigV1.Info&{// plugin_origins is derived state, not a persisted config field.plugin_origins?: ConfigPlugin.Origin[]}functionwritable(info: Info){const{plugin_origins: _plugin_origins, ...next}=inforeturnnext}
mergePluginOrigins is append-only — never prunes
constmergePluginOrigins=Effect.fnUntraced(function*(source: string,list: ConfigPlugin.Spec[]|undefined,kind?: ConfigPlugin.Scope,){if(!list?.length)returnconsthit=kind??(yield*pluginScopeForSource(source))// Merge newly seen plugin origins with previously collected ones, then dedupe.// NOTE: This only deduplicates — it NEVER removes entries absent from current config sources.constplugins=ConfigPlugin.deduplicatePluginOrigins([
...(result.plugin_origins??[]),// <-- carries forward ALL previous entries
...list.map((spec)=>({ spec, source,scope: hit})),])result.plugin=plugins.map((item)=>item.spec)result.plugin_origins=plugins})
The function mergePluginOriginsonly adds and deduplicates — it never starts from a clean slate. The spread ...(result.plugin_origins ?? []) carries forward every previously-merged entry, even if the source config file that declared it no longer contains it.
Auto-discovery also cannot explain it
The ConfigPlugin.load(dir) function scans {plugin,plugins}/*.{ts,js} within each config directory. The stale plugin is at D:\plugins\bug-compaction.ts — not in any standard config directory. Auto-discovery cannot produce this path.
Hypothesis
A stale plugin_origins entry from an earlier session is being carried forward by the append-only merge. Since plugin_origins is stripped by writable() before serialization, it should be rebuilt each startup. The fact that it persists suggests either:
A Desktop v2 migration (v1.18.0) cached plugin state outside the standard config path
The sidecar server process retains plugin state in an unaccounted-for storage layer (possibly in opencode.db or an indexed store not accessible via filesystem search)
mergePluginOrigins is being called with stale data from a source not captured by the config file audit (well-known URL, OPENCODE_CONFIG_CONTENT, etc.)
Activity
mocun33 commentedon Jul 15, 2026
Evidence: Startup Error Persists
From %APPDATA%\ai.opencode.desktop\opencode.global.dat\ (
otification\ key) — the error is recorded every startup:
\
Failed to load plugin file:///D:/plugins/bug-compaction.ts:
Cannot find module 'D:\\plugins\\bug-compaction.ts' imported from
C:\\Users\\0\\AppData\\Local\\Programs\\@opencode-aidesktop\\resources\\app.asar\\out\\main\\chunks\\node-BxVSsTOf.js
\\
This error appears across multiple startup sessions (timestamps span different runs), confirming the plugin registry survives restart.
mocun33 commentedon Jul 15, 2026
Evidence: Clean Config & plugin-meta
opencode.jsonc plugin array — 5 entries, none is bug-compaction:
plugin-meta.json (%APPDATA%\ai.opencode.desktop\opencode\plugin-meta.json) — only oh-my-openagent, no stale entry:
{ oh-my-openagent:tui: { id: oh-my-openagent:tui, source: npm, spec: oh-my-openagent, target: C:\\Users\\0\\.cache\\opencode\\packages\\oh-my-openagent@latest\\node_modules\\oh-my-openagent, requested: latest, version: 4.11.1 } }electron-store (.dat files) — All 19 .dat files searched, zero match for bug-compaction or D:/plugins.
mocun33 commentedon Jul 15, 2026
Source Code Analysis
From
packages/opencode/src/config/config.ts(Desktop app.asar decompiled, v1.18.1):plugin_originsis derived statemergePluginOriginsis append-only — never prunesThe function
mergePluginOriginsonly adds and deduplicates — it never starts from a clean slate. The spread...(result.plugin_origins ?? [])carries forward every previously-merged entry, even if the source config file that declared it no longer contains it.Auto-discovery also cannot explain it
The
ConfigPlugin.load(dir)function scans{plugin,plugins}/*.{ts,js}within each config directory. The stale plugin is atD:\plugins\bug-compaction.ts— not in any standard config directory. Auto-discovery cannot produce this path.Hypothesis
A stale
plugin_originsentry from an earlier session is being carried forward by the append-only merge. Sinceplugin_originsis stripped bywritable()before serialization, it should be rebuilt each startup. The fact that it persists suggests either:mergePluginOriginsis being called with stale data from a source not captured by the config file audit (well-known URL, OPENCODE_CONFIG_CONTENT, etc.)mocun33 commentedon Jul 17, 2026
v1.18.3 update: ghost no longer generates NEW errors on restart
Upgraded to Desktop v1.18.3. After restart:
opencode.global.datnotification history -- no new entries forbug-compaction.tssince restartbug-compactionreferences in store are from pre-v1.18.3 runsviewed:falsein notification history but Desktop no longer actively tries to load the ghost pluginThis might mean v1.18.3 partially addresses the issue (stops the loading attempt), but old notification entries are never cleaned up.
Partial fix or just different behaviour in my specific case.
github-actions commentedon Sep 17, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.