Skip to content

[SQLite]: Skip blank statement chunks and reject empty migrations - #6208

Open
jsiu93 wants to merge 1 commit into
drizzle-team:mainfrom
jsiu93:fix/sqlite-migrator-skip-blank-statements
Open

[SQLite]: Skip blank statement chunks and reject empty migrations#6208
jsiu93 wants to merge 1 commit into
drizzle-team:mainfrom
jsiu93:fix/sqlite-migrator-skip-blank-statements

Conversation

@jsiu93

@jsiu93 jsiu93 commented Aug 29, 2026

Copy link
Copy Markdown

Why

Migration SQL is split on --> statement-breakpoint and each chunk is executed as-is. Hand-edited files can leave a whitespace-only chunk (for example a trailing breakpoint), and a drizzle-kit generate --custom placeholder is blank until it is filled in. SQLite drivers do not agree on what to do with an empty statement: better-sqlite3 throws RangeError: The supplied SQL string contains no statements, libsql and sql-js accept it, and expo-sqlite crashes in native code (expo/expo#49066). On the strict drivers the migration transaction never completes, and on Expo the app dies before any JS error surfaces.

Closes #6207.

How

SQLiteSyncDialect.migrate and SQLiteAsyncDialect.migrate now take their statements from a shared migrationStatements() helper in sqlite-core/dialect.ts:

  • whitespace-only chunks are dropped before the driver sees them;
  • a migration with no statements left throws a DrizzleError naming its timestamp, so the transaction rolls back and the migration is not recorded. A forgotten custom placeholder therefore fails loudly with one readable error on every driver instead of a driver-specific RangeError or a native crash, and it cannot be marked as applied.

Hash bookkeeping and the __drizzle_migrations insert are unchanged. The filter lives in sqlite-core rather than in each driver's readMigrationFiles, so every SQLite driver (better-sqlite3, bun, libsql, sql-js, d1, durable objects, expo, op-sqlite, proxy) gets the same behaviour from one place.

Tests

Two new cases in integration-tests/tests/sqlite/better-sqlite.test.ts:

  • migrator skips blank statement chunks (fixture drizzle2/sqlite-blank-statements/, trailing breakpoint): applies and records the migration. Fails on main with the RangeError above.
  • migrator rejects a migration with no statements (fixture drizzle2/sqlite-empty-migration/, single-newline custom migration): throws contains no SQL statements, no table created, no migration recorded.

Run locally (no Docker): better-sqlite 137 passed, sql-js 137 passed, libsql-sqlite3 138 passed. The Docker-backed Postgres and MySQL suites were not run; the change only touches sqlite-core.

Breakpoint splitting and hand-edited migration files can leave
whitespace-only chunks, and a `drizzle-kit generate --custom` placeholder
is blank until it is filled in. Passing those to SQLite drivers aborts the
migration: better-sqlite3 throws a RangeError, while expo-sqlite can crash
in native code (expo/expo#49066).

Drop whitespace-only chunks before running a migration in both the sync
and async SQLite migrators. A migration with nothing left to run now fails
with a DrizzleError naming its timestamp instead of being recorded as
applied, so a forgotten custom placeholder cannot slip past silently.

The better-sqlite3 regression tests cover a trailing breakpoint (applied
and recorded) and an empty placeholder (rejected, transaction rolled back).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jsiu93 jsiu93 changed the title [SQLite]: Skip blank statements when applying migrations [SQLite]: Skip blank statement chunks and reject empty migrations Aug 29, 2026
@jsiu93
jsiu93 force-pushed the fix/sqlite-migrator-skip-blank-statements branch from 8e54a81 to a45d8f2 Compare August 29, 2026 22:53
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]: SQLite migrator passes blank statements to the driver (throws on better-sqlite3, crashes natively on expo-sqlite)

1 participant