Conversation
A detector keyed on v1-table presence misclassifies every store that went through OpenCode's official 1.18 → 2.x in-place upgrade: the migration keeps the retired message/part tables beside the new session_v2 ones, so the store reads as v1 and the v2 fail-closed assert refuses generation-specific access on every read. On opencode 2.x hosts this surfaced as every prompt interrupting within ~20 ms of submission: the plugin's session hook fails during setup, the host swallows the error, and no model call is ever made. session_v2 is an unambiguous v2 signal — OpenCode 1.18.x never creates it while every 2.x store does — so prefer it over the v1-message heuristic. Pure 1.18.x stores (no session_v2) keep reading as v1.
|
Waiting for This PR needs a linked issue with the |
| @@ -168,225 +168,225 @@ | |||
| "adm-zip": "0.6.0", | |||
| }, | |||
| "packages": { | |||
| "@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.82", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.27" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-WKKou2wbhGGYV8PSALAPyV2YY4nfCqCPkyBzYtJtDA9yCcIFwsbtkTNgg7bqtLCVzeEsY7wwxRoCWy+EMfrw/A=="], | |||
| "@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.82", "https://registry.npmmirror.com/@ai-sdk/anthropic/-/anthropic-3.0.82.tgz", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.27" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-WKKou2wbhGGYV8PSALAPyV2YY4nfCqCPkyBzYtJtDA9yCcIFwsbtkTNgg7bqtLCVzeEsY7wwxRoCWy+EMfrw/A=="], | |||
There was a problem hiding this comment.
Third-party registry breaks installs
The regenerated lockfile pins every dependency tarball to registry.npmmirror.com, although the repository has no committed configuration for that registry. CI uses bun install --frozen-lockfile, so an unavailable or blocked mirror will break installs across the project. Restore the default resolution entries or configure this registry as an intentional, separate change.
| schema: "main" | "oc_backfill" = "main", | ||
| ): OpenCodeStoreGeneration { | ||
| const tables = schemaTableNames(db, schema); | ||
| if (tables.has("session_v2")) return "v2"; |
There was a problem hiding this comment.
Prioritizing session_v2 also affects runToolOwnerBackfill. Migrated stores retain the legacy message and part tables that this backfill reads, but this line now classifies them as v2 before the backfill's hard-coded v1 assertion. The assertion therefore throws during a normal database open, leaving eligible legacy tool-owner rows to the slower lazy-adoption fallback instead of completing the intended boot-time backfill. The backfill must explicitly accept migrated stores whose legacy tables remain.
Review feedback (PR cortexkit#486): prioritizing session_v2 also flipped runToolOwnerBackfill's hard-coded v1 assert — migrated stores retain the legacy message/part tables this backfill reads, but now detect as v2, so the assert threw during a normal database open and every eligible legacy row silently degraded to the slower lazy-adoption fallback. Gate on what the backfill actually needs — the v1 message tables being present — via the new hasV1MessageTables helper, instead of asserting a single generation. Pure v2 stores (tables absent) still fail fast with a clearer message. Also restore bun.lock to the upstream resolution (CI runs bun install --frozen-lockfile; the local mirror-pinned regeneration was flagged by review).
|
Both review findings addressed in 145eb11:
Verified: shared+v2+features suites — 2197 pass, 1 fail where the failing test (transformers-node-wasm fixture, builds a model from network) also fails on unmodified master under the same sandbox, so it is unrelated to this change. |
|
Thanks for the detailed incident report and for identifying the retained-table backfill requirement. I reproduced the key schema fact with a fresh OpenCode 1.18.30 store: it creates We are going ahead with #477 for the main fix rather than superseding it with this PR. The deciding case is downgrade: after a store has been used by OpenCode 2 and then by OpenCode 1 again, Your D2 observation is useful and we will carry it. #477 does not currently throw in the backfill because its detector still returns v1 for the mixed store, but gating that job on the presence of the One repository issue at the current head: Closing this PR in favour of #477; #489 stays open as the tracking point for the D2 follow-up. |
Problem
A store that went through OpenCode's official 1.18 → 2.x in-place upgrade is misclassified as a v1 store, and the v2 fail-closed assert then refuses generation-specific access on every read:
The official migration keeps the retired
message/parttables beside the newsession_v2/session_messageones (tens of thousands of legacy rows on a long-lived install), sodetectOpenCodeStoreGeneration— keyed on v1-table presence — reads every migrated store as v1.Impact (observed on opencode 2.0.5/2.0.8 hosts)
Every prompt interrupts within ~20 ms of submission: the plugin's session hook fails during setup, the host swallows the error (zero server-side log lines at the moment of death), and no model call is ever made. Sessions show
user → idle(interrupted)with no assistant turn. A clean-install store on the same host version works fine, which makes this look host-version-specific and sent us chasing opencode regressions for a long while before the mismatch warn surfaced in debug logs.Fix
session_v2is an unambiguous v2 signal — OpenCode 1.18.x never creates it while every 2.x store does — so prefer it over the v1-message heuristic:Pure 1.18.x stores (no
session_v2) keep reading as v1; the pinned live-1.18 fixture test is unchanged and still passes.Tests
message+part+session+project+session_v2+session_message) detects as v2, asserts v2 fine, and asserts v1 throws.packages/plugin/src/shared+src/v2pass, 0 fail.Related note
The 0.42.6 v2 lane also calls
context.model.list()directly (pre-catalogshape), which throws on opencode 2.0.3 hosts whose plugin context predates themodeldomain — same swallowed-error instant-interrupt symptom. Main already usescontext.catalog.model.list, so that one looks resolved on main; mentioning it here since the two combined made 0.42.6 fatal on 2.0.3.Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Summary by cubic
Fixes store generation detection so stores migrated through OpenCode's official 1.18 → 2.x upgrade are treated as v2 instead of v1, and keeps the legacy tool-owner backfill working on those stores.
Bug Fixes
session_v2is now the strongest v2 signal; pure 1.18.x stores without it still detect as v1.bun.lockto the upstream resolution sobun install --frozen-lockfilepasses.Written for commit 145eb11. Summary will update on new commits.
The store-detection and backfill fixes appear sound, but the PR is not yet safe to merge because the lockfile still depends on an unconfigured third-party registry.
Findings
Summary
The PR corrects OpenCode store-generation detection and its related legacy owner-backfill behavior.
session_v2as the strongest v2 schema signal, including when migrated stores retain v1 tables.messageandparttables.bun.lockremains outstanding.Diagram
%%{init: {'theme': 'neutral'}}%% flowchart TD A[Inspect OpenCode schema] --> B{session_v2 exists?} B -->|Yes| C[Classify as v2] B -->|No| D{message and part exist?} D -->|Yes| E[Classify as v1] D -->|No| F{session_message exists?} F -->|Yes| C F -->|No| G[Empty or unknown] C --> H{Legacy message tables remain?} E --> H H -->|Yes| I[Run best-effort tool-owner backfill] H -->|No| J[Skip backfill and use lazy adoption]Reviews (2) · Last reviewed commit: "fix(backfill): accept migrated stores in..."
Closes #489