toeverything/AFFiNE · error · Error

A migration name is required

Error message

A migration name is required

What it means

Thrown by RevertCommand.execute(name?) — the 'data revert' CLI command — when no migration name argument was provided. Reverting requires knowing exactly which migration to roll back, so an undefined name is a usage error.

Solutions

  1. Pass the exact migration name to revert: 'node cli.js data revert <migrationName>'.
  2. If you don't know the name, query the dataMigration table (SELECT name FROM "DataMigration") for applied migrations.
  3. Quote the name in the shell to preserve any special characters.

Example fix

// before
$ node cli.js data revert
// after
$ node cli.js data revert add-notification-guessed-1698900000
Defensive patterns

Strategy: validation

Validate before calling

// Guard the CLI wrapper
if (typeof argv._[1] !== 'string' || !argv._[1]) {
  console.error('Usage: data revert <migration-name>');
  process.exit(1);
}
await revertCommand.execute(argv._[1]);

Prevention

When it happens

Trigger: Running 'node cli.js data revert' with no argument.

Common situations: Operator assumes revert defaults to the last applied migration (it does not); shell quoting swallowed the argument; automation script parameter left empty.

Understand the failure class

Background: "no subcommand specified" and "... is required": CLI errors when a required argument is missing — this error's family across 13 libraries.

Related errors


AI-assisted analysis of toeverything/AFFiNE@591f874dad (2026-08-18). Data as JSON: /api/errors/60bb4ac3fede6a6c. Report an issue: GitHub.

Appendix: source

Thrown at packages/backend/server/src/data/commands/run.ts:176

      data: {
        finishedAt: new Date(),
      },
    });
  }
}

@Injectable()
export class RevertCommand {
  logger = new Logger(RevertCommand.name);

  constructor(
    private readonly db: PrismaClient,
    private readonly injector: ModuleRef
  ) {}

  async execute(name?: string): Promise<void> {
    if (!name) {
      throw new Error('A migration name is required');
    }

    const migrations = collectMigrations();

    const migration = migrations.find(m => m.name === name);

    if (!migration) {
      this.logger.error('Available migration names:');
      migrations.forEach(m => {
        this.logger.error(`  - ${m.name}`);
      });
      throw new Error(`Unknown migration name: ${name}.`);
    }

    const record = await this.db.dataMigration.findFirst({
      where: {
        name: migration.name,
      },

View on GitHub (pinned to 591f874dad)