vitessio/vitess · error

invalid value for on-ddl: %v

Error message

invalid value for on-ddl: %v

What it means

commandVReplicationWorkflow validates the --on-ddl flag against the known OnDDLAction enum values in binlogdatapb (e.g. IGNORE, STOP, EXEC, EXEC_IGNORE). The flag is uppercased first; if the value is still not in the enum, this error names the invalid value.

Source

Thrown at go/vt/vtctl/vtctl.go:2135

	*sourceShards = strings.TrimSpace(*sourceShards)
	deferNonPKeys := subFlags.Bool("defer-secondary-keys", true, "Defer secondary index creation for a table until after it has been copied.")

	// Reshard params
	targetShards := subFlags.String("target_shards", "", "Reshard only. Target shards")
	*targetShards = strings.TrimSpace(*targetShards)
	skipSchemaCopy := subFlags.Bool("skip_schema_copy", false, "Reshard only. Skip copying of schema to target shards")

	if err := subFlags.Parse(args); err != nil {
		return err
	}

	if subFlags.NArg() != 2 {
		return errors.New("two arguments are needed: action, keyspace.workflow")
	}

	onDDL = strings.ToUpper(onDDL)
	if _, ok := binlogdatapb.OnDDLAction_value[onDDL]; !ok {
		return fmt.Errorf("invalid value for on-ddl: %v", onDDL)
	}

	action := subFlags.Arg(0)
	ksWorkflow := subFlags.Arg(1)
	target, workflowName, err := splitKeyspaceWorkflow(ksWorkflow)
	if err != nil {
		return err
	}
	_, err = wr.TopoServer().GetKeyspace(ctx, target)
	if err != nil {
		wr.Logger().Errorf("keyspace %s not found", target)
		return err
	}

	vrwp := &wrangler.VReplicationWorkflowParams{
		TargetKeyspace: target,
		Workflow:       workflowName,
		DryRun:         *dryRun,

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Use one of: IGNORE, STOP, EXEC, EXEC_IGNORE (case-insensitive)
  2. Check `vtctl MoveTables --help` for the accepted on-ddl values
  3. Update scripts/configs that carry non-enum values
  4. If you need different behavior, file/discuss a feature rather than inventing values

Example fix

// before
vtctl MoveTables -on-ddl=SKIP ... 
// after
vtctl MoveTables -on-ddl=EXEC_IGNORE ...
Defensive patterns

Strategy: validation

Validate before calling

valid_on_ddl() {
  case "$(echo "$1" | tr '[:lower:]' '[:upper:]')" in
    IGNORE|STOP|EXEC|EXEC_IGNORE) return 0 ;;
    *) echo "invalid on-ddl: $1"; return 1 ;;
  esac
}
valid_on_ddl "$ON_DDL" || exit 1

Try / catch

if err := runVtctl("MoveTables", "--on-ddl="+onDDL, ...); err != nil {
    if strings.Contains(err.Error(), "invalid value for on-ddl") {
        // default to EXEC_IGNORE or surface enum options to the operator
    }
}

Prevention

When it happens

Trigger: Passing --on-ddl with a value not in {IGNORE, STOP, EXEC, EXEC_IGNORE} to MoveTables, Reshard, or Migrate — e.g. 'ignore' is fine (uppercased), but 'SKIP' or 'EXECUTE' are not.

Common situations: Using MySQL-ish terminology ('SKIP') instead of the Vitess enum; scripts written against another tool's flag vocabulary; lowercase values are fine, so the failure indicates a genuinely wrong word.

Understand the failure class

Background: "unknown output mode", "invalid value for flag", "expects true/false": fixing invalid flag value errors in CLI tools — this error's family across 24 libraries.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/d436d7071b74f3f9. Report an issue: GitHub.