payloadcms/payload · error · Error
Migration ${migration.name} not found locally.
Error message
Migration ${migration.name} not found locally. What it means
Thrown by `migrateRefresh` (`payload migrate:fresh`-style refresh: roll back all then re-apply) when a migration recorded in the DB has no corresponding local file. Identical root cause to error 172 but triggered during a full refresh: the loop reverses every recorded migration and needs each one's `down` function. A single missing file stops the whole refresh.
Source
Thrown at packages/payload/src/database/migrations/migrateRefresh.ts:34
const { existingMigrations } = await getMigrations({
payload,
})
const req = await createLocalReq({}, payload)
if (existingMigrations?.length) {
payload.logger.info({
msg: `Rolling back all ${existingMigrations.length} migration(s).`,
})
// Reverse order of migrations to rollback
existingMigrations.reverse()
for (const migration of existingMigrations) {
try {
const migrationFile = migrationFiles.find((m) => m.name === migration.name)
if (!migrationFile) {
throw new Error(`Migration ${migration.name} not found locally.`)
}
payload.logger.info({ msg: `Migrating down: ${migration.name}` })
const start = Date.now()
await initTransaction(req)
const session = payload.db.sessions?.[await req.transactionID!]
await migrationFile.down({ payload, req, session })
payload.logger.info({
msg: `Migrated down: ${migration.name} (${Date.now() - start}ms)`,
})
await payload.delete({
collection: 'payload-migrations',
req,
where: {
name: {
equals: migration.name,
},
},View on GitHub (pinned to 00c58b35c0)
Solutions
- Restore all missing migration files from git so every recorded migration has a `down()`.
- If some are intentionally gone, delete their rows from `payload-migrations` before refreshing.
- Avoid deleting applied migration files; archive instead.
Example fix
# before: refresh fails on missing file payload migrate:fresh # after: restore files, then refresh git checkout HEAD -- src/migrations/ payload migrate:fresh
Defensive patterns
Strategy: validation
Validate before calling
import { readdir } from 'fs/promises'
const local = new Set((await readdir('./src/migrations')).map(stripExt))
const { docs } = await payload.find({ collection: 'payload-migrations', limit: 0 })
const missing = docs.filter((m) => !local.has(m.name))
if (missing.length) throw new Error(`Cannot refresh; missing files: ${missing.map((m) => m.name).join(', ')}`) Try / catch
try {
await payload.db.migrateRefresh()
} catch (err) {
if (/not found locally/.test((err as Error).message)) {
// restore all missing files or purge their DB rows before re-running
}
throw err
} Prevention
- Keep the full set of applied migrations in the repo.
- Validate file/DB sync before running migrate:fresh.
- Do not prune old migration files in deployed artifacts.
When it happens
Trigger: Running `payload migrate:refresh`/`fresh` with a migration in the DB whose file was removed; branch switching that drops a previously-applied migration file; a deploy that pruned older migration files.
Common situations: Resetting a staging DB after migration cleanup; onboarding scripts that run refresh against a DB seeded by an older code version.
Related errors
- Migration ${migration.name} not found locally.
- Error importing migration file from ${importPath}
- Invalid database type given. Valid types are: ${Object.value
- Migration ${migration.name} not found locally.
- Failed to download: ${url}
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/7354187e6cc728ff.
Report an issue: GitHub.