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
- Use one of: IGNORE, STOP, EXEC, EXEC_IGNORE (case-insensitive)
- Check `vtctl MoveTables --help` for the accepted on-ddl values
- Update scripts/configs that carry non-enum values
- 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
- Use only the enum values IGNORE, STOP, EXEC, EXEC_IGNORE
- Define on-ddl choices as a fixed set in automation UIs/configs
- Note case-insensitivity: casing is fine, wrong words are not
- Keep vitess terminology in runbooks, not MySQL migration vocabularies
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
- invalid action for Migrate: %s
- either source or target shards are missing
- validateWorkflowName.VReplicationExec: <dynamic validation.m
- invalid tablet type %v: %v
- type %v is not one of: %v
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/d436d7071b74f3f9.
Report an issue: GitHub.