{"record":{"id":"16c3048123d8b112","repo":"remix-run/remix","slug":"applied-migration-row-id-row-name-is-missing","errorCode":null,"errorMessage":"Applied migration \"{row.id}_{row.name}\" is missing from current migrations","messagePattern":"Applied migration \"(.+?)_(.+?)\" is missing from current migrations","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/data-table/src/lib/migrations/runner.ts","lineNumber":109,"sourceCode":"\nasync function assertMigrationIntegrity(\n  migrations: MigrationDescriptor[],\n  journal: MigrationJournalRow[],\n  direction: MigrationDirection,\n): Promise<void> {\n  let migrationMap = new Map(migrations.map((migration) => [migration.id, migration]))\n\n  for (let row of journal) {\n    let migration = migrationMap.get(row.id)\n\n    if (!migration) {\n      // Rolling back must stay possible when journal rows have no matching\n      // migration files, so only forward runs hard-error on orphaned entries.\n      if (direction === 'down') {\n        continue\n      }\n\n      throw new Error(\n        'Applied migration \"' + row.id + '_' + row.name + '\" is missing from current migrations',\n      )\n    }\n\n    let expected = await computeChecksum(migration)\n\n    if (expected !== row.checksum) {\n      throw new Error(\n        'Migration checksum drift detected for \"' +\n          row.id +\n          '\" (journal=' +\n          row.checksum +\n          ', current=' +\n          expected +\n          ')',\n      )\n    }\n  }","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/data-table/src/lib/migrations/runner.ts#L91-L127","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"-- before: journal has row 20240101123045_create_users but file deleted\n-- after: either restore migrations/20240101123045_create_users/\n-- or remove the journal row:\nDELETE FROM _migrations WHERE id = '20240101123045';","handlingStrategy":"try-catch","validationCode":"let known = new Set(registry.list().map((m) => `${m.id}_${m.name}`))\nlet rows = await db.select().from(journalTable)\nlet orphans = rows.filter((row) => !known.has(`${row.id}_${row.name}`))\nif (orphans.length > 0 && direction === 'up') {\n  throw new Error('orphaned journal rows: ' + orphans.map((r) => r.id).join(', '))\n}","typeGuard":null,"tryCatchPattern":"try {\n  await runMigrations(db, { direction: 'up' })\n} catch (error) {\n  if (error instanceof Error && error.message.includes('missing from current migrations')) {\n    // restore the file, or clean the journal row, then retry\n  }\n  throw error\n}","preventionTips":["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."],"tags":["migrations","journal","missing-migration","integrity"],"backgroundTag":"applied-migration-missing","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}