payloadcms/payload · error · Error
Migration ${migration.name} not found locally.
Error message
Migration ${migration.name} not found locally. What it means
Thrown by `migrateReset`, which rolls back every applied migration in reverse order to fully reset the database schema. Like the down/refresh variants, it requires that each row in `payload-migrations` has a corresponding local migration file exposing a `down()` function; if any name has no file, the reset cannot proceed.
Source
Thrown at packages/drizzle/src/migrateReset.ts:38
const migrationFiles = await readMigrationFiles({ payload })
const { existingMigrations } = await getMigrations({ payload })
if (!existingMigrations?.length) {
payload.logger.info({ msg: 'No migrations to reset.' })
return
}
const req = await createLocalReq({}, payload)
existingMigrations.reverse()
// Rollback all migrations in order
for (const migration of existingMigrations) {
const migrationFile = migrationFiles.find((m) => m.name === migration.name)
try {
if (!migrationFile) {
throw new Error(`Migration ${migration.name} not found locally.`)
}
const start = Date.now()
payload.logger.info({ msg: `Migrating down: ${migrationFile.name}` })
await initTransaction(req)
const db = await getTransaction(this, req)
await migrationFile.down({ db, payload, req })
payload.logger.info({
msg: `Migrated down: ${migrationFile.name} (${Date.now() - start}ms)`,
})
const tableExists = await migrationTableExists(this, db)
if (tableExists) {
await payload.delete({
id: migration.id,
collection: 'payload-migrations',
req,
})View on GitHub (pinned to 00c58b35c0)
Solutions
- Restore the missing migration file(s) from git so the local set matches the DB rows, then re-run reset.
- On a disposable database, prefer `payload migrate:fresh` (drop+recreate) to avoid depending on every historical `down()`.
- Delete orphaned rows in `payload-migrations` for files you intentionally removed, then retry reset.
- Double-check the adapter's migration directory is the one that originally produced these migrations.
Example fix
// before: payload migrate:reset fails on 'Migration 0003_indexes not found locally.' // after: restore file or wipe DB // git checkout main -- src/migrations/0003_indexes.ts && payload migrate:reset // or for dev: payload migrate:fresh
Defensive patterns
Strategy: validation
Validate before calling
// Pre-check before reset
const files = await readMigrationFiles({ payload })
const { existingMigrations } = await getMigrations({ payload })
const known = new Set(files.map(f => f.name))
if (existingMigrations.some(m => !known.has(m.name))) {
throw new Error('Aborting reset: some applied migrations lack local files')
}
await payload.db.migrateReset() Type guard
null
Try / catch
try {
await payload.db.migrateReset()
} catch (err) {
if (/not found locally/.test(String(err?.message))) {
payload.logger.warn(`Reset blocked by drift; run migrate:fresh to recreate the DB.`)
}
throw err
} Prevention
- Archive, don't delete, historical migration files.
- Use migrate:fresh on disposable databases to avoid depending on old down() functions.
- Keep the migrationDir stable across branches.
When it happens
Trigger: Calling `payload migrate:reset` (or the adapter's `migrateReset`) when the `payload-migrations` table contains a row whose migration file is absent from the migration directory read by `readMigrationFiles`.
Common situations: Resetting a long-lived DB whose older migration files were archived/deleted; branch switching that leaves orphaned DB rows; renamed migrations without a corresponding DB-row update; wrong `migrationDir`.
Related errors
- Migration ${migration.name} not found locally.
- Migration ${migration.name} not found locally.
- No previous migration schema file found! A prior migration f
- Either collection or globalSlug must be passed.
- Either collectionSlug or globalSlug must be provided
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/fe26f70c2006fca1.
Report an issue: GitHub.