{"record":{"id":"c51cb2d723ce8c93","repo":"toeverything/AFFiNE","slug":"migration-name-has-not-been-executed","errorCode":null,"errorMessage":"Migration ${name} has not been executed.","messagePattern":"Migration (.+?) has not been executed\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/backend/server/src/data/commands/run.ts","lineNumber":160,"sourceCode":"\n    const migration = migrations.find(m => m.name === name);\n\n    if (!migration) {\n      this.logger.error('Available migration names:');\n      migrations.forEach(m => {\n        this.logger.error(`  - ${m.name}`);\n      });\n      throw new Error(`Unknown migration name: ${name}.`);\n    }\n\n    const record = await this.db.dataMigration.findFirst({\n      where: {\n        name: migration.name,\n      },\n    });\n\n    if (!record) {\n      throw new Error(`Migration ${name} has not been executed.`);\n    }\n\n    try {\n      this.logger.log(`Reverting ${name}...`);\n      await migration.down(this.db, this.injector);\n      this.logger.log('Done reverting');\n    } catch (e) {\n      this.logger.error(`Failed to revert data migration ${name}`, e);\n    }\n\n    await this.db.dataMigration.delete({\n      where: {\n        id: record.id,\n      },\n    });\n  }\n}\n","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/26c515e050211269e911f7d9cfe162a26c83ed98/packages/backend/server/src/data/commands/run.ts#L142-L178","documentation":"Thrown by RevertCommand.execute(name) in packages/backend/server/src/data/commands/run.ts:160 when reverting a data migration. Before calling migration.down(), the command looks up a finished record in the dataMigration table (written by RunCommand.runMigration on success). If no record exists, the migration was never run (or never finished), so there is nothing to revert. This is a plain Error, not a UserFriendlyError, so it surfaces as an internal server error to API callers.","triggerScenarios":"Invoking the data-migration revert flow (RevertCommand.execute) with a migration name that has no corresponding row in the dataMigration table. The name resolves to a known migration file (otherwise the 'Unknown migration name' error at run.ts:150 fires first), but findFirst by name returns null.","commonSituations":"Running revert on a fresh database where 'run' was never executed; reverting a migration whose up() failed midway (RunCommand.runMigration deletes the record on failure at run.ts:106); reverting after a manual DB wipe of the dataMigration table; passing a migration name that exists in code but was added after the current DB state.","solutions":["Run the forward migrations first (RunCommand.execute) so a dataMigration record exists, then revert.","Verify state in the DB: SELECT * FROM dataMigration WHERE name = '<name>'; if absent, the migration was never completed.","If the migration genuinely was never applied and you want its down() to run anyway, call migration.down() directly rather than via RevertCommand.","Check server logs for a prior 'Failed to run data migration' entry (run.ts:112) indicating the up() failed and rolled back."],"exampleFix":"// before\nawait revertCommand.execute('addUserFlags1700000000000');\n// after\nconst ran = await db.dataMigration.findFirst({ where: { name: 'addUserFlags1700000000000' } });\nif (!ran) {\n  logger.warn('Migration was never executed; nothing to revert.');\n} else {\n  await revertCommand.execute('addUserFlags1700000000000');\n}","handlingStrategy":"validation","validationCode":"const record = await db.dataMigration.findFirst({ where: { name: migrationName } });\nif (!record) {\n  logger.warn(`Skip revert: ${migrationName} was never executed.`);\n  return;\n}\nawait revertCommand.execute(migrationName);","typeGuard":"const isExecutedMigration = (r: { id: string; finishedAt: Date | null } | null): r is { id: string; finishedAt: Date | null } =>\n  r !== null;","tryCatchPattern":null,"preventionTips":["Always run forward migrations (RunCommand.execute) before invoking RevertCommand.","Treat the absence of a dataMigration row as 'nothing to revert', not an error.","Inspect SELECT * FROM dataMigration WHERE name=? before reverting in production."],"tags":["migration","data-migration","database","cli"],"backgroundTag":null,"analyzedSha":"26c515e050211269e911f7d9cfe162a26c83ed98","analyzedAt":"2026-08-12T13:15:16.447Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}