Skip to content

fix(core): import legacy drizzle migration journals without a name column - #37707

Open
seongilp wants to merge 1 commit into
anomalyco:devfrom
seongilp:fix/legacy-drizzle-journal-import
Open

fix(core): import legacy drizzle migration journals without a name column#37707
seongilp wants to merge 1 commit into
anomalyco:devfrom
seongilp:fix/legacy-drizzle-journal-import

Conversation

@seongilp

Copy link
Copy Markdown

Issue for this PR

Closes #31119

Type of change

  • Bug fix

What does this PR do?

Databases whose __drizzle_migrations journal was written by drizzle-orm's stock migrator have the old (id, hash, created_at) schema — no name column. On these databases every startup crashes with no such column: name. In the TUI the error never reaches the screen, so it looks like a silent freeze (blank/unresponsive, empty log file); opencode models prints the error directly.

The crash is in DatabaseMigration.applyOnly: when the migration table is empty it seeds it with SELECT name FROM __drizzle_migrations, assuming the journal is already at v1. The v0 -> v1 journal upgrade exists in effect-drizzle-sqlite (upgradeIfNeeded), but it only runs inside that package's migrate(), which core no longer calls for these databases — so v0 journals never get upgraded and the seed query dies.

Fix: introspect the journal's columns before seeding. If name is missing, map each row's created_at back to the timestamp prefix of the TypeScript migration ids. This is the same value the v0 -> v1 upgrader matches on: drizzle-kit derives the migration filename prefix from the same timestamp it stores in created_at. Rows that map to no known migration abort with a descriptive error instead of the raw SQL error.

How did you verify your code works?

  • Two new tests in database-migration.test.ts reproduce the legacy journal schema taken from a real affected database (including the empty hash values). Without the fix they fail with exactly no such column: name; with it the file passes 17/17.
  • Ran the patched CLI against a copy of a real broken database from an affected install: the 6 legacy journal rows seeded to the correct migration ids, the remaining 32 migrations applied on top, pragma quick_check returns ok, and existing session/project rows are intact.
  • tsgo --noEmit, oxlint, and prettier are clean (no new warnings).

Screenshots / recordings

Not a UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

…lumn

Journals written by drizzle-orm's stock migrator only have (id, hash,
created_at) columns, so the seeding query in DatabaseMigration.applyOnly
crashed with 'no such column: name' on every startup. Map created_at back
to the migration id's timestamp prefix instead, mirroring the v0 -> v1
journal upgrade in effect-drizzle-sqlite.
@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Potential duplicate or related PR found:

Why it might be related: Both PRs address legacy database migration issues in core. PR #34188 handles migrating legacy local databases, while PR #37707 specifically addresses importing legacy drizzle migration journals without the name column. These are likely complementary fixes for database compatibility.

@seongilp

Copy link
Copy Markdown
Author

Re: the bot's note about #34188 — I found that PR (and the now-closed #31121) after opening this one, so a quick note on how this differs, for whoever triages:

Both detect the legacy (id, hash, created_at) journal the same way. The difference is the seeding fallback:

  • fix(core): migrate legacy local databases #34188 seeds by row count: input.slice(0, count) marks the first N TypeScript migrations completed, assuming the journal rows correspond 1:1 to the first N migrations in order. Nothing validates that assumption; if it doesn't hold the wrong migrations get marked completed silently.
  • This PR maps each row's created_at back to the timestamp prefix of a known migration id — the same value the effect-drizzle-sqlite v0 -> v1 journal upgrader matches on (drizzle-kit derives the filename prefix from the timestamp it stores in created_at). Rows that don't map to any known migration abort with a descriptive error instead of seeding anything.

Verified against a real affected database (6 legacy journal rows, empty hashes): all rows mapped to the correct ids and the remaining migrations applied cleanly on top. This PR also keeps the diff to the migration path only.

Happy to defer to whichever approach the maintainers prefer — mostly want #31119 fixed, since affected installs currently freeze on startup with no visible error.

@starcraft66

Copy link
Copy Markdown

Just used this PR to fix an old hanging install of opencode 👍

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.

[BUG]: Error: no such column: name

2 participants