drizzle-team / drizzle-team/drizzle-orm

[BUG]: SQLite migrator passes blank statements to the driver (throws on better-sqlite3, crashes natively on expo-sqlite)

Open
#6,207 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.