drizzle-team / drizzle-team/drizzle-orm
[BUG]: SQLite migrator passes blank statements to the driver (throws on better-sqlite3, crashes natively on expo-sqlite)
- Dominant language
- TypeScript
- Stars
- 35.8k
- Forks
- 1.6k
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 4
Description
### What version of `drizzle-orm` are you using?
0.45.2
### What version of `drizzle-kit` are you using?
0.31.10
### Other packages
expo-sqlite 57.0.1 (where the crash surfaced), better-sqlite3 11.9.1 (where the error is reproducible on Node)
### Describe the Bug
`readMigrationFiles` splits each migration on `--> statement-breakpoint` without dropping whitespace-only chunks, and `SQLiteSyncDialect.migrate` / `SQLiteAsyncDialect.migrate` (`drizzle-orm/src/sqlite-core/dialect.ts`) run every chunk through the driver. Two common inputs produce a blank chunk:
- a whitespace-only chunk left in a hand-edited file (for example a trailing `--> statement-breakpoint`), and
- the empty placeholder file that `drizzle-kit generate --custom` writes before you fill it in.
What happens:
- better-sqlite3 rejects the chunk with `RangeError: The supplied SQL string contains no statements`, so the whole migration transaction fails.
- expo-sqlite 57.0.1 passes the empty statement to native code and the app dies with `EXC_BAD_ACCESS` in `SQLiteModule.run → sqlite3_clear_bindings` (the native side is tracked in expo/expo#49066). We hit this variant in a real Expo app: every cold start crashed until the placeholder was filled and Metro's cache cleared.
Expected: whitespace-only chunks are skipped, and a migration with nothing left to run fails with one readable Drizzle error (instead of a driver-specific RangeError or a native crash) and is not recorded as applied, so a forgotten custom placeholder cannot slip past silently.
Reproduction (Node, no Docker): fixture folder with `0000_*.sql` ending in `--> statement-breakpoint\n`, `0001_*.sql` containing a single newline, `meta/_journal.json` with both entries; then `migrate(db, { migrationsFolder })` on a better-sqlite3 `:memory:` database. Fails on `main`; fix with both cases as regression tests in #6208.
Contributor guide
Research direction
Start with readMigrationFiles and SQLiteSyncDialect.migrate / SQLiteAsyncDialect.migrate in drizzle-orm/src/sqlite-core/dialect.ts, then reproduce the issue with the described better-sqlite3 fixture. Add regression coverage for trailing statement-breakpoint whitespace and an empty custom migration, using the cases in #6208 as a guide. Done means blank chunks are skipped, empty migrations produce one readable Drizzle error, and are not recorded as applied.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- sqlite, typescript
- Domain
- database, testing
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100