semaphoreui/semaphore · error

Cannot specify both --undo-to and --apply-to

Error message

Cannot specify both --undo-to and --apply-to

What it means

The semaphore migrate command panics when both --undo-to and --apply-to flags are supplied. The two flags are mutually exclusive: one performs a forward apply, the other a rollback, and applying both directions in a single invocation is ambiguous.

Solutions

  1. Remove one of the two flags: keep only --apply-to to migrate forward or only --undo-to to roll back
  2. Run the two operations as separate sequential commands if you need to undo then re-apply
  3. Check the command help (`semaphore migrate --help`) for supported flag combinations

Example fix

// before
semaphore migrate --apply-to 2.1 --undo-to 2.0
// after
semaphore migrate --undo-to 2.0   # rollback only
# or separately:
semaphore migrate --apply-to 2.1  # forward only
Defensive patterns

Strategy: validation

Validate before calling

if [ -n "$UNDO_TO" ] && [ -n "$APPLY_TO" ]; then echo "use --apply-to or --undo-to, not both"; exit 1; fi
semaphore migrate --apply-to "$APPLY_TO"

Prevention

When it happens

Trigger: Running `semaphore migrate --apply-to <version> --undo-to <version>` — the Run function panics immediately when both migrationArgs.undoTo and migrationArgs.applyTo are non-empty.

Common situations: Copy-pasting a rollback command and appending a forward-migration flag; scripting migration chains and forgetting to remove --undo-to from a template; misreading docs about flag precedence.

Understand the failure class

Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.

Related errors


AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07). Data as JSON: /api/errors/fdecbe56ceac14a0. Report an issue: GitHub.

Appendix: source

Thrown at cli/cmd/migrate.go:32

}

func init() {
	migrateCmd.PersistentFlags().StringVar(&migrationArgs.undoTo, "undo-to", "", "Undo to specific version")
	migrateCmd.PersistentFlags().StringVar(&migrationArgs.applyTo, "apply-to", "", "Apply to specific version")
	migrateCmd.PersistentFlags().IntVar(&migrationArgs.errLogSize, "err-log-size", 0, "Error log size")
	migrateCmd.PersistentFlags().BoolVar(&migrationArgs.skipTaskOutput, "skip-task-output", false, "Skip task output importing during migration")
	migrateCmd.PersistentFlags().BoolVar(&migrationArgs.mergeExistingUsers, "merge-existing-users", false, "Reuse existing users matched by username instead of failing on conflict")

	rootCmd.AddCommand(migrateCmd)
}

var migrateCmd = &cobra.Command{
	Use:   "migrate",
	Short: "Execute migrations",
	Run: func(cmd *cobra.Command, args []string) {

		if migrationArgs.undoTo != "" && migrationArgs.applyTo != "" {
			panic("Cannot specify both --undo-to and --apply-to")
		}

		var undoTo, applyTo *string

		if migrationArgs.undoTo != "" {
			undoTo = &migrationArgs.undoTo
		}

		if migrationArgs.applyTo != "" {
			applyTo = &migrationArgs.applyTo
		}

		store := createStoreWithMigrationVersion("migrate", undoTo, applyTo)

		defer store.Close()
		util.Config.PrintDbInfo()
	},
}

View on GitHub (pinned to 1774ccb71a)