{"record":{"id":"28b3913dd948a63d","repo":"n8n-io/n8n","slug":"migrationclassname-migration-name-is-wrong-mig","errorCode":null,"errorMessage":"${migrationClassName} migration name is wrong. Migration class name should have a JavaScript timestamp appended.","messagePattern":"(.+?) migration name is wrong\\. Migration class name should have a JavaScript timestamp appended\\.","errorType":"exception","errorClass":"TypeORMError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/typeorm/src/migration/MigrationExecutor.ts","lineNumber":531,"sourceCode":"\t\t\t.getRawMany();\n\t\treturn migrationsRaw.map((migrationRaw) => {\n\t\t\treturn new Migration(\n\t\t\t\tparseInt(migrationRaw['id']),\n\t\t\t\tparseInt(migrationRaw['timestamp']),\n\t\t\t\tmigrationRaw['name'],\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Gets all migrations that setup for this connection.\n\t */\n\tprotected getMigrations(): Migration[] {\n\t\tconst migrations = this.connection.migrations.map((migration) => {\n\t\t\tconst migrationClassName = migration.name || (migration.constructor as any).name;\n\t\t\tconst migrationTimestamp = parseInt(migrationClassName.substr(-13), 10);\n\t\t\tif (!migrationTimestamp || isNaN(migrationTimestamp)) {\n\t\t\t\tthrow new TypeORMError(\n\t\t\t\t\t`${migrationClassName} migration name is wrong. Migration class name should have a JavaScript timestamp appended.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn new Migration(undefined, migrationTimestamp, migrationClassName, migration);\n\t\t});\n\n\t\tthis.checkForDuplicateMigrations(migrations);\n\n\t\t// sort them by timestamp\n\t\treturn migrations.sort((a, b) => a.timestamp - b.timestamp);\n\t}\n\n\tprotected checkForDuplicateMigrations(migrations: Migration[]) {\n\t\tconst migrationNames = migrations.map((migration) => migration.name);\n\t\tconst duplicates = Array.from(\n\t\t\tnew Set(\n\t\t\t\tmigrationNames.filter(","sourceCodeStart":513,"sourceCodeEnd":549,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/typeorm/src/migration/MigrationExecutor.ts#L513-L549","documentation":"TypeORM orders migrations by parsing the trailing 13 characters of each migration class name as a millisecond timestamp (`parseInt(name.substr(-13), 10)`). If the class name does not end in a 13-digit numeric timestamp the parse yields NaN and TypeORM throws, because it cannot determine execution order. This runs inside `getMigrations()`, invoked by run/show/generate/revert.","triggerScenarios":"Naming a migration class by hand, e.g. `class InitialSchema extends Migration` instead of `class InitialSchema1700000000000`. Renaming a migration and dropping the numeric suffix. Copying a migration file and changing the class name without preserving the 13-digit suffix.","commonSituations":"Hand-authoring a migration instead of using the generator (`migration:generate`), which names the file/class with `Date.now()`. A linter/formatter stripping trailing digits. Importing migrations from a barrel that re-exports under a different name.","solutions":["Rename the class so it ends in exactly 13 digits, e.g. `class AddUserTable1700000000000`. Use the current `Date.now()` value.","Regenerate the migration with the CLI so naming stays consistent.","Audit every entry in the `migrations` array and fix any whose name fails `/\\d{13}$/`."],"exampleFix":"// before\nclass AddUserTable extends Migration { async up() {} }\n\n// after\nclass AddUserTable1700000000000 extends Migration { async up() {} }","handlingStrategy":"validation","validationCode":"// Validate every configured migration class name ends in a 13-digit timestamp\nconst NAME_RE = /\\d{13}$/;\nfor (const m of dataSource.migrations) {\n  const name = m.name || (m as any).constructor.name;\n  if (!NAME_RE.test(name) || Number.isNaN(parseInt(name.slice(-13), 10))) {\n    throw new Error(`Migration ${name} must end in a 13-digit timestamp`);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always generate migrations with the CLI so names carry `Date.now()`.","Add a precheck (above) in your test setup so a bad name fails fast.","Never rename a migration class without preserving the 13-digit suffix."],"tags":["typeorm","migrations","naming-convention","configuration"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}