Repository navigation
OpenCode V2: every turn refused in silence with 0.43.2 — v2 refuseIfUnsafe / "context storage is not durable" (outcome=interrupted, no assistant message) #546
Description
Summary
On OpenCode V2 (2.0.18), loading @cortexkit/opencode-magic-context (npm latest 0.43.2, freshly installed) makes every session turn die in silence: the user message is stored, the turn is refused before the provider call, the host records idle {outcome:"interrupted"} ~60–360 ms later, and no assistant message is ever produced. The TUI shows no reply and no visible error. Same symptom class as the closed #493; still reproducible with the current npm release on this host.
Environment
- OpenCode V2:
2.0.18(both~/tools/ocv2/opencodeand~/.opencode/bin/opencode2), Linux - magic-context:
0.43.2— reproduced with the previously cached install and with a fresh install after clearing~/.cache/opencode/npm/@cortexkit/opencode-magic-context@latest(new cache dir created, version verified 0.43.2) - V1:
1.18.32with the same plugin on the same host works normally (its Magic Context transforms run; see the plugin log) - Context store:
~/.local/share/cortexkit/magic-context/context.db(118 MB,journal_mode=wal, WAL ~6 MB, actively written; the store is V1-era — the plugin log contains historicalrefusing to migrate … from upstream migration v79 to v85lines from 2026-09-24) ~/.local/share/opencode/opencode.dbis ~2.7 GB and shared by V1+V2 on this host
Symptom / evidence
session_message rows (~/.local/share/opencode/opencode.db) for a refused turn:
seq 4 user "say PB-shared" t=…4983132
seq 5 idle {"outcome":"interrupted"} t=…4983492 ← 360 ms later; no assistant row
Console trace at refusal time (observed in a standalone V2 run):
[magic-context] v2 refuseIfUnsafe warn: context storage is not durable
Timeline: last successful assistant message = 2026-09-26 21:28:52 (before V2 had ever loaded plugins on this host); the V2 plugin caches were first populated 21:34–35 that day; every V2 turn since has been interrupted.
Controlled experiment (minimal repro)
Standalone V2 server (opencode --standalone, isolated XDG_CONFIG_HOME) with a minimal opencode.json containing exactly one plugin entry; submit a message; read session_message.outcome:
| plugin loaded | outcome |
|---|---|
| (none) | succeeded — assistant reply generated (tokens billed) |
only oh-my-opencode-slim |
succeeded |
only a local herdr reporting plugin (V2 setup() no-op) |
succeeded |
only @cortexkit/opencode-magic-context@latest (fresh 0.43.2) |
interrupted, no assistant message |
Code pointers (master)
packages/plugin/src/v2/hooks/context.ts:709and:838—if (!db || !isDatabasePersisted(db)) throw new Error("context storage is not durable");packages/plugin/src/v2/hooks/context.ts:277—reportPreProviderRefusal()→console.warn("[magic-context] v2 refuseIfUnsafe", error); its comment states the host then stores the turn as interrupted and the user simply never receives a reply — no error on screen and no assistant message.packages/plugin/src/v2/hooks/context.ts:1291–1305— refusals are thrown asV2ContextRefusal(a fail-open branch exists only forcompactionOff).packages/plugin/src/features/magic-context/storage-db.ts:2529—isDatabasePersisted(db)returns a WeakMap flag set during database open;getDatabasePersistenceError(db)holds the reason and is not surfaced anywhere user-visible.- On this host the plugin's own session log (
$TMPDIR/opencode/magic-context/magic-context.log) contains nov2 refusing this turn before the model calllines for the V2 refusals — the only trace is the console warning.
Related
- opencode plugins: V2 primary-session prompt hangs when @cortexkit/opencode-magic-context@0.42.6 is loaded #493 (closed): V2 prompts hang with 0.42.6 — "fixed on master" comment at 2026-09-25T19:03Z; npm latest 0.43.2 was published 2026-09-25T11:25Z, i.e. before that comment. If the fix isn't in 0.43.2, this report is the released-channel recurrence; if it is, this refusal path (
context storage is not durable) appears to be a distinct one. - OpenCode V2: first-request history reconciliation blocks the event loop for 154 seconds on a large migrated session #536 (open): first-request history reconciliation blocking on a large migrated session — the store here is also large and V1-migrated.
Expected
- Degrade / fail open when durable context storage cannot be established (or at minimum surface a user-visible refusal reason), instead of silently killing every turn.
- If this is the opencode plugins: V2 primary-session prompt hangs when @cortexkit/opencode-magic-context@0.42.6 is loaded #493 class: the v2 store reader should accept, repair, or doctor-guided migrate the store present on this host.
Repro steps
- V2 config with only this plugin:
{"$schema":"https://opencode.ai/config.json","plugin":["@cortexkit/opencode-magic-context@latest"]} opencode --standalone(or any V2 server) and send any prompt.- Observe: no assistant reply;
session_message=user→idle {outcome:"interrupted"}; console =v2 refuseIfUnsafe+context storage is not durable.
Activity
magic-alfonso commentedon Sep 27, 2026
Thanks for the detailed report and the controlled experiment. They point at a likely cause. I haven't confirmed it on your host yet, so please check the two things below.
Likely cause. OpenCode 1 and OpenCode 2 share one Magic Context database (
context.db). Therefusing to migrate … from upstream migration v79 to v85lines in your log mean the database is still at an old schema version. 0.43.2 needs version 90, so the first OpenCode 2 process that opens it has to migrate it. Magic Context deliberately refuses to migrate while another OpenCode server or Pi process is still running an older plugin build against the same database: migrating under it would make that older host fail closed. You run OpenCode 1.18.32 with the plugin on the same host, so if that OpenCode 1 server loads an older Magic Context build, OpenCode 2 refuses to migrate on every start. Magic Context then has no usable storage in that process, and every turn is refused. That matches what you see.Where the real reason is logged. OpenCode 2 writes Magic Context's log to a separate path,
$TMPDIR/opencode2/magic-context/magic-context.log, not$TMPDIR/opencode/magic-context/magic-context.log. That's why you found no refusal lines. Could you check the OpenCode 2 log for a line starting with[magic-context] storage fatal:orupstream migration lane at bootfrom a recent start, and paste it here? If this is the cause, it names the blocking process ID.Which build OpenCode 1 loads. Could you also share the Magic Context entry from your OpenCode 1 config (is it pinned to a version?), and the output of
npx @cortexkit/magic-context@latest doctor?Workaround, if the log confirms it. Stop the OpenCode 1 server, or update its cached plugin to 0.43.2 and restart it. Then start OpenCode 2 once, so it migrates the database with nothing old attached. After that, both hosts run on 0.43.2 against the same database.
What we'll fix regardless. A turn refused like this must not end in silence. The refusal should carry the actual reason (the migration was refused because a named process still uses an older build) instead of the generic "context storage is not durable", and
doctorshould report this situation directly. I'll follow up here with the fix.mason: name the storage refusal reason and retry the open on OpenCode…
mason: keep OpenCode 2 storage notices off the wire and recover histo…
mason: bring the v0.44.0 release notes up to date with master
magic-alfonso commentedon Sep 28, 2026
This is in 0.44.0. When OpenCode 2 couldn't open
context.db, every turn was refused with nothing on screen, and the log said only "context storage is not durable". Now:[Magic Context storage notice]is stored in the conversation. It is never sent to the model;doctorreads the schema version built into every cached Magic Context copy on both OpenCode 1 and OpenCode 2. If a copy is behind the database, the check fails and names the directory and how to refresh it.For your setup: update both hosts. On OpenCode 2 use
/plugins(ctrl+u on Magic Context) oropencode plugin update, and refresh OpenCode 1's cached plugin as well. Stop any OpenCode 1 server still running an older build, restart both hosts on 0.44.0, and runnpx @cortexkit/magic-context@latest doctor --fix. We never confirmed the cause on your host, so if turns are still refused on 0.44.0, the refusal now says why. Please paste it here.