{"record":{"id":"b3c9249859c6cbd0","repo":"remix-run/remix","slug":"options-step-and-to-are-mutually-exclusive","errorCode":null,"errorMessage":"Options --step and --to are mutually exclusive","messagePattern":"Options --step and --to are mutually exclusive","errorType":"exception","errorClass":"UsageError","httpStatus":null,"severity":"error","filePath":"packages/cli/src/lib/commands/db.ts","lineNumber":150,"sourceCode":"    return { command, ...parsed.options }\n  }\n\n  if (command === 'rollback') {\n    let parsed = parseArgs(\n      commandArgv,\n      {\n        connectionEnv: connectionOption,\n        dryRun: { flag: '--dry-run', type: 'boolean' },\n        journalTable: journalOption,\n        migrations: migrationsOption,\n        step: { flag: '--step', type: 'string' },\n        to: { flag: '--to', type: 'string' },\n      },\n      { maxPositionals: 0 },\n    )\n\n    if (parsed.options.step !== undefined && parsed.options.to !== undefined) {\n      throw invalidOptionValue('Options --step and --to are mutually exclusive')\n    }\n\n    let { step: rawStep, ...options } = parsed.options\n    return { command, ...options, step: parseStepOption(rawStep) }\n  }\n\n  if (command === 'reset') {\n    let parsed = parseArgs(\n      commandArgv,\n      {\n        connectionEnv: connectionOption,\n        force: { flag: '--force', type: 'boolean' },\n        journalTable: journalOption,\n        migrations: migrationsOption,\n        seed: seedOption,\n      },\n      { maxPositionals: 0 },\n    )","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/cli/src/lib/commands/db.ts#L132-L168","documentation":"For remix db migrate, the --step (migrate N steps) and --to (migrate up to a specific migration) options select the migration endpoint and cannot be combined; passing both is rejected.","triggerScenarios":"parseDbCommandArgs for the migrate branch finds both parsed.options.step and parsed.options.to defined, e.g. remix db migrate --step 2 --to 0003_add_users.","commonSituations":"Copy-pasting flags from history; scripts that always pass --to and add --step conditionally; misunderstanding that the two are alternative endpoint selectors.","solutions":["Keep only one endpoint option: either --step N or --to <migration-id>","Drop the irrelevant flag from scripts/CI invocations","Re-read remix db migrate --help to pick the right selector for the goal"],"exampleFix":"# before\n$ remix db migrate --step 2 --to 0003_add_users\n\n# after\n$ remix db migrate --to 0003_add_users","handlingStrategy":"validation","validationCode":"function validMigrateOptions(argv: string[]): boolean {\n  return !(argv.includes('--step') || argv.some((a) => a.startsWith('--step=')) &&\n           argv.includes('--to') || argv.some((a) => a.startsWith('--to=')))\n}","typeGuard":null,"tryCatchPattern":"try {\n  runDbCommand(['migrate', ...flags], context)\n} catch (error) {\n  if (/mutually exclusive/.test(error.message)) failFast('pick --step or --to, not both')\n  else throw error\n}","preventionTips":["Model endpoint selection as a single variable in scripts (steps OR target)","Generate migration commands from one source of truth in tooling","Keep --help output handy when authoring CI migration steps"],"tags":["cli","database","arguments","mutually-exclusive"],"backgroundTag":"mutually-exclusive-flags","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}