toeverything/AFFiNE · critical · Error
Invalid migration name: ${migration.name}
Error message
Invalid migration name: ${migration.name} What it means
Thrown by `collectMigrations` when a migration module's `name` does not end in a run of digits (regex `/([\d]+)$/`). The trailing number is parsed as the migration's run `order`; without it, `Number(undefined)` yields `NaN` and the loader aborts. A plain `Error` (no error code), thrown during module-load/CLI bootstrap.
Source
Thrown at packages/backend/server/src/data/commands/run.ts:21
import { PrismaClient } from '@prisma/client';
import { once } from 'lodash-es';
import * as migrationImports from '../migrations';
interface Migration {
name: string;
always?: boolean;
up: (db: PrismaClient, injector: ModuleRef) => Promise<void>;
down: (db: PrismaClient, injector: ModuleRef) => Promise<void>;
order: number;
}
export const collectMigrations = once(() => {
const migrations = Object.values(migrationImports).map(migration => {
const order = Number(migration.name.match(/([\d]+)$/)?.[1]);
if (Number.isNaN(order)) {
throw new Error(`Invalid migration name: ${migration.name}`);
}
return {
name: migration.name,
// @ts-expect-error optional
always: migration.always,
up: migration.up,
down: migration.down,
order,
};
}) as Migration[];
return migrations.sort((a, b) => a.order - b.order);
});
@Injectable()
export class RunCommand {
logger = new Logger(RunCommand.name);View on GitHub (pinned to 26c515e050)
Solutions
- Rename the offending migration file so it ends in digits — conventionally a millisecond timestamp prefix, e.g. `1766000000000-my-migration.ts`.
- Match the existing naming pattern in `packages/backend/server/src/data/migrations/` (all are `<digits>-slug.ts`).
- Re-run the migration command after renaming to confirm `collectMigrations` no longer throws.
- Update any scaffolding/generator template so new migrations always get a numeric suffix.
Example fix
// before: src/data/migrations/add-indexes.ts // (loader throws: Invalid migration name: add-indexes) // after: rename to // src/data/migrations/1766000000000-add-indexes.ts
Defensive patterns
Strategy: validation
Validate before calling
// Enforce naming convention in a generator/scaffold
function migrationFilename(slug) {
const ts = Date.now();
return `${ts}-${slug}.ts`; // always ends in digits before .ts
} Type guard
function hasNumericSuffix(name) {
return /\d+$/.test(name);
} Prevention
- Always name migration files with a trailing numeric suffix (timestamp convention).
- Follow the existing `<digits>-slug.ts` pattern in data/migrations.
- Lint migration filenames in CI to catch malformed names before runtime.
When it happens
Trigger: Adding a migration file whose name lacks a trailing numeric suffix — e.g. `add-indexes.ts` instead of `1766000000000-add-indexes.ts`. The loader iterates every exported migration module at startup and fails on the first malformed name.
Common situations: New migration added without following the `timestamp-slug.ts` naming convention; renaming a migration file and dropping the numeric prefix; migration file generated by a scaffold that did not append the timestamp.
Related errors
- Unknown migration name: ${name}.
- A migration name is required
- A config file path is required
- invalid_app_config_input
- Migration ${name} has not been executed.
AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12).
Data as JSON: /api/errors/6acaae8002202f2c.
Report an issue: GitHub.