vitessio/vitess · error

invalid on-ddl action: %s

Error message

invalid on-ddl action: %s

What it means

When updating a workflow (e.g. MoveTables/VReplication update), the --on-ddl flag value is validated against the binlogdatapb.OnDDLAction enum map (upper-cased). If the string is not one of the known enum names, this error is returned before any topo change.

Source

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

				if len(*tabletTypesStrs) > 0 && strings.HasPrefix((*tabletTypesStrs)[0], discovery.InOrderHint) {
					(*tabletTypesStrs)[0] = strings.TrimPrefix((*tabletTypesStrs)[0], discovery.InOrderHint)
					inorder = true
				}
				for i, tabletType := range *tabletTypesStrs {
					tabletTypes[i], err = topoproto.ParseTabletType(tabletType)
					if err != nil {
						return err
					}
				}
			} else {
				tabletTypes = textutil.SimulatedNullTabletTypeSlice
			}
			onddl := int32(textutil.SimulatedNullInt) // To signify no value has been provided
			if subFlags.Lookup("on-ddl").Changed {    // Validate the provided value
				changes = true
				ival, valid := binlogdatapb.OnDDLAction_value[strings.ToUpper(*onDDL)]
				if !valid {
					return fmt.Errorf("invalid on-ddl action: %s", *onDDL)
				}
				onddl = ival
			}
			if !changes {
				return errors.New(errWorkflowUpdateWithoutChanges)
			}
			tsp := tabletmanagerdatapb.TabletSelectionPreference_UNKNOWN
			if inorder {
				tsp = tabletmanagerdatapb.TabletSelectionPreference_INORDER
			}
			rpcReq = &tabletmanagerdatapb.UpdateVReplicationWorkflowRequest{
				Workflow:                  workflow,
				Cells:                     *cells,
				TabletTypes:               tabletTypes,
				TabletSelectionPreference: &tsp,
			}
			if onddl != int32(textutil.SimulatedNullInt) {
				rpcReq.(*tabletmanagerdatapb.UpdateVReplicationWorkflowRequest).OnDdl = new(binlogdatapb.OnDDLAction(onddl))

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Use one of the valid values (case-insensitive): IGNORE, STOP, EXEC, EXEC_IGNORE
  2. Run `vtctldclient Workflow update --help` to see allowed --on-ddl values
  3. Normalize the value in scripts to upper case before passing

Example fix

// before
vtctldclient Workflow update commerce/sales --on-ddl execute
// after
vtctldclient Workflow update commerce/sales --on-ddl EXEC
Defensive patterns

Strategy: validation

Validate before calling

validOnDDL := map[string]bool{"IGNORE":true,"STOP":true,"EXEC":true,"EXEC_IGNORE":true}
if !validOnDDL[strings.ToUpper(onDDL)] {
	return fmt.Errorf("--on-ddl must be one of IGNORE|STOP|EXEC|EXEC_IGNORE, got %s", onDDL)
}

Try / catch

if err := updateWorkflow(...); err != nil {
	if strings.Contains(err.Error(), "invalid on-ddl action") {
		return fmt.Errorf("use EXEC_IGNORE etc. (upper-cased enum names): %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Running `vtctldclient Workflow update <ks>/<wf> --on-ddl <value>` where value is not IGNORE/STOP/EXEC/EXEC_IGNORE (case-insensitive).

Common situations: Typo like 'execute' or 'skip'; lowercase variants like 'execignore' without underscore; scripts passing an old flag value from a previous Vitess version.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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