remix-run/remix · error · Error
Cannot combine "to" and "step" migration options in the same
Error message
Cannot combine "to" and "step" migration options in the same run
What it means
The migration runner was given both `to` (a target migration) and `step` (a count) in the same options object. These define conflicting end conditions for the run, so the combination is rejected up front.
Source
Thrown at packages/data-table/src/lib/migrations/runner.ts:58
migrations: MigrationDescriptor[]
journalTable: string
direction: MigrationDirection
options: MigrationOperationOptions
}
function assertStepOption(step: number | undefined): void {
if (step === undefined) {
return
}
if (!Number.isInteger(step) || step < 1) {
throw new Error('Invalid migration step option. Expected a positive integer.')
}
}
function assertMigrationOperationOptions(options: MigrationOperationOptions): void {
if (options.to !== undefined && options.step !== undefined) {
throw new Error('Cannot combine "to" and "step" migration options in the same run')
}
}
function resolveTargetOption(
migrations: MigrationDescriptor[],
to: string | undefined,
): string | undefined {
if (to === undefined) {
return undefined
}
// Accept either a bare migration id or the full `id_name` directory form and
// normalize to the bare id so range filtering compares ids consistently.
let matches = migrations.filter(
(migration) => migration.id === to || migration.id + '_' + migration.name === to,
)
if (matches.length === 0) {View on GitHub (pinned to 9696913134)
Solutions
- Remove one of the two options: either target an id with `to`, or a count with `step`.
- If defaults set `step`, override it to `undefined` when specifying `to`: `{ step: undefined, to }`.
- Add CLI flag mutual-exclusion checks before invoking the runner.
Example fix
// before
await runMigrations(db, { direction: 'up', to, step })
// after
await runMigrations(db, { direction: 'up', to }) Defensive patterns
Strategy: validation
Validate before calling
if (options.to !== undefined && options.step !== undefined) {
delete options.step // or reject with a clear CLI error
} Prevention
- Make --to and --step mutually exclusive in your CLI flag parser.
- Avoid spreading default option objects that carry `step` when `to` is set.
When it happens
Trigger: Calling runMigrations with `{ to: '20240101123045_create_users', step: 3 }` — both keys defined triggers assertMigrationOperationOptions inside runMigrationsUnlocked.
Common situations: Spreading a defaults object containing `step` into options that also set `to`; CLI flags `--to X --step N` passed together.
Related errors
- Invalid migration step option. Expected a positive integer.
- Unknown migration target: {to}
- expected promise to resolve, but it rejected with: ${stringi
- ${optionName} values must be package names. Received "${pack
- fingerprint cannot be used with watch mode
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/865138ba2290ae35.
Report an issue: GitHub.