remix-run/remix · critical · Error
Applied migration "{row.id}_{row.name}" is missing from curr
Error message
Applied migration "{row.id}_{row.name}" is missing from current migrations What it means
The migration journal (applied-migrations table) contains a row whose `id_name` has no matching migration file in the current registry. Forward (`up`) runs hard-error on such orphans because the chain of applied migrations can no longer be reasoned about; `down` runs are allowed so you can roll back past the gap.
Source
Thrown at packages/data-table/src/lib/migrations/runner.ts:109
async function assertMigrationIntegrity(
migrations: MigrationDescriptor[],
journal: MigrationJournalRow[],
direction: MigrationDirection,
): Promise<void> {
let migrationMap = new Map(migrations.map((migration) => [migration.id, migration]))
for (let row of journal) {
let migration = migrationMap.get(row.id)
if (!migration) {
// Rolling back must stay possible when journal rows have no matching
// migration files, so only forward runs hard-error on orphaned entries.
if (direction === 'down') {
continue
}
throw new Error(
'Applied migration "' + row.id + '_' + row.name + '" is missing from current migrations',
)
}
let expected = await computeChecksum(migration)
if (expected !== row.checksum) {
throw new Error(
'Migration checksum drift detected for "' +
row.id +
'" (journal=' +
row.checksum +
', current=' +
expected +
')',
)
}
}View on GitHub (pinned to 9696913134)
Solutions
- Restore the missing migration file/directory so the journal entry matches again.
- If the removal was intentional, manually delete the orphaned journal row (or recreate the DB) before the next `up` run.
- For branch switching, roll back (`direction: 'down'`) past the orphan first — down runs tolerate missing files.
Example fix
-- before: journal has row 20240101123045_create_users but file deleted -- after: either restore migrations/20240101123045_create_users/ -- or remove the journal row: DELETE FROM _migrations WHERE id = '20240101123045';
Defensive patterns
Strategy: try-catch
Validate before calling
let known = new Set(registry.list().map((m) => `${m.id}_${m.name}`))
let rows = await db.select().from(journalTable)
let orphans = rows.filter((row) => !known.has(`${row.id}_${row.name}`))
if (orphans.length > 0 && direction === 'up') {
throw new Error('orphaned journal rows: ' + orphans.map((r) => r.id).join(', '))
} Try / catch
try {
await runMigrations(db, { direction: 'up' })
} catch (error) {
if (error instanceof Error && error.message.includes('missing from current migrations')) {
// restore the file, or clean the journal row, then retry
}
throw error
} Prevention
- Never delete or rename applied migration files; add new migrations instead.
- Validate journal rows against the registry before forward runs in deploy scripts.
- Remember `down` runs still work — use them to roll back past orphans.
When it happens
Trigger: Running `runMigrations(db, { direction: 'up', ... })` after deleting/renaming a migration file that was previously applied, or running `up` against a database whose journal references migrations from another branch.
Common situations: Deleting a squashed migration without updating the journal; branching where a DB kept migrations removed from main; renaming a migration directory after it was applied.
Related errors
- Migration checksum drift detected for "{row.id}" (journal={r
- expected promise to resolve, but it rejected with: ${stringi
- ${optionName} values must be package names. Received "${pack
- Cannot combine "to" and "step" migration options in the same
- Duplicate migration id "{id}" inferred from directory "{dire
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/16c3048123d8b112.
Report an issue: GitHub.