{"record":{"id":"3b03cefbf7e3bc37","repo":"payloadcms/payload","slug":"migration-migration-name-not-found-locally-3b03ce","errorCode":null,"errorMessage":"Migration ${migration.name} not found locally.","messagePattern":"Migration (.+?) not found locally\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/drizzle/src/migrateRefresh.ts","lineNumber":45,"sourceCode":"  if (!existingMigrations?.length) {\n    payload.logger.info({ msg: 'No migrations to rollback.' })\n    return\n  }\n\n  payload.logger.info({\n    msg: `Rolling back batch ${latestBatch} consisting of ${existingMigrations.length} migration(s).`,\n  })\n\n  const req = await createLocalReq({}, payload)\n\n  // Reverse order of migrations to rollback\n  existingMigrations.reverse()\n\n  for (const migration of existingMigrations) {\n    try {\n      const migrationFile = migrationFiles.find((m) => m.name === migration.name)\n      if (!migrationFile) {\n        throw new Error(`Migration ${migration.name} not found locally.`)\n      }\n\n      payload.logger.info({ msg: `Migrating down: ${migration.name}` })\n      const start = Date.now()\n      await initTransaction(req)\n      const db = await getTransaction(this, req)\n      await migrationFile.down({ db, payload, req })\n      payload.logger.info({\n        msg: `Migrated down:  ${migration.name} (${Date.now() - start}ms)`,\n      })\n\n      const tableExists = await migrationTableExists(this, db)\n      if (tableExists) {\n        await payload.delete({\n          collection: 'payload-migrations',\n          req,\n          where: {\n            name: {","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/drizzle/src/migrateRefresh.ts#L27-L63","documentation":"Same root cause as the other 'Migration not found locally' errors, but raised by `migrateRefresh`, which rolls back ALL applied migrations (in reverse) and is typically used to re-run the full migration set during development. The adapter reads applied migrations from the `payload-migrations` table and tries to find each one's file via `readMigrationFiles`; a name with no local file aborts the refresh before any re-run can happen.","triggerScenarios":"Running `payload migrate:refresh` (rollback-all then migrate-up) when one or more rows in `payload-migrations` reference migration files that no longer exist in the configured migration directory.","commonSituations":"Migration files pruned/renamed during a refactor while the DB still records them; switching branches whose migration histories diverge; CI/preview DB seeded by a branch whose files were later removed; `migrationDir` pointing somewhere stale.","solutions":["Restore every missing migration file named in the failure from version control so the local set is a superset of the DB rows.","For a throwaway dev/preview DB, clear the drift with `payload migrate:fresh` rather than refresh.","Manually remove orphaned rows from `payload-migrations` for migrations you intentionally deleted, then re-run refresh.","Confirm the `migrationDir` used by the adapter matches the directory the migrations were generated into."],"exampleFix":"// before: payload migrate:refresh fails with 'Migration 0001_init not found locally.'\n// after: bring the file back, or wipe the dev DB\n//   git restore src/migrations/0001_init.ts && payload migrate:refresh\n// or: payload migrate:fresh","handlingStrategy":"validation","validationCode":"// Verify all DB migrations have local files before refresh\nconst files = await readMigrationFiles({ payload })\nconst { existingMigrations } = await getMigrations({ payload })\nconst fileNames = new Set(files.map(f => f.name))\nconst orphans = existingMigrations.filter(m => !fileNames.has(m.name))\nif (orphans.length) {\n  throw new Error(`Cannot refresh: ${orphans.map(o => o.name).join(', ')} missing locally`)\n}\nawait payload.db.migrateRefresh()","typeGuard":"null","tryCatchPattern":"try {\n  await payload.db.migrateRefresh()\n} catch (err) {\n  if (/Migration .* not found locally/.test(String(err?.message))) {\n    // decide: restore files, or wipe with migrate:fresh\n  }\n  throw err\n}","preventionTips":["Keep migration history append-only.","For dev, prefer migrate:fresh over refresh when history is untrusted.","Verify migrationDir is consistent across environments."],"tags":["migrations","drizzle","database-drift","refresh"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}