From 6e9e0ab3bc3b7a589452224538117fa4ddfc673f Mon Sep 17 00:00:00 2001 From: MdTanwer Date: Tue, 15 Sep 2026 19:53:13 +0000 Subject: [PATCH] fix(core): fail fast when DB schema is ahead of current runtime When Desktop, CLI, or a plugin migrate the shared opencode.db forward, an older binary that opens the same file will now die at startup with a clear error instead of silently proceeding and crashing inside a SQL query handler. The guard computes the set difference (completed IDs in DB) - (known IDs in binary). A non-empty result means the DB was advanced by a newer runtime; Effect.die surfaces the unknown migration IDs and suggests two remedies: upgrade or isolate via OPENCODE_DB. Closes #49177 Closes #38471 Closes #35403 --- packages/core/src/database/migration.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/core/src/database/migration.ts b/packages/core/src/database/migration.ts index 644b22ab7a26..8f9a9e1f81b1 100644 --- a/packages/core/src/database/migration.ts +++ b/packages/core/src/database/migration.ts @@ -93,6 +93,20 @@ export function applyOnly(db: Database, input: Migration[]) { } } + // Guard: if the DB's migration table contains IDs this binary has never heard + // of, the schema was advanced by a newer runtime. Fail fast here rather than + // silently opening an incompatible database and crashing deep inside a query. + const knownIds = new Set(input.map((m) => m.id)) + const unknownAhead = [...completed].filter((id) => !knownIds.has(id)) + if (unknownAhead.length > 0) + return yield* Effect.die( + new Error( + `Database schema is newer than this OpenCode runtime. ` + + `Unknown migration(s): ${unknownAhead.join(", ")}. ` + + `Upgrade your CLI or Desktop to match, or set OPENCODE_DB to use a separate database file.`, + ), + ) + for (const migration of input) { if (completed.has(migration.id)) continue yield* db.transaction((tx) =>