vitessio/vitess · error

invalid action ;

Error message

invalid action %s; %s

What it means

A second default-case guard at the end of commandVDiff2 returns the same 'invalid action' message after the switch (a defensive/legacy path). Like 1033 it fires when the action verb is not one of the recognized VDiff actions, appending usage help.

Solutions

  1. Read the usage text included in the error and use a valid action.
  2. Correct typos in the action verb.
  3. Align scripts with the action set of the installed Vitess version.
  4. Use `show all` as the safe discovery action when unsure.

Example fix

// before
VDiff -- commerce.move.tables cancle bd2f3e5a-...
// after
VDiff -- commerce.move.tables stop bd2f3e5a-...
Defensive patterns

Strategy: validation

Validate before calling

const known = new Set(["show", "stop", "resume", "delete"])
if (!known.has(action)) {
  throw new Error(`Unknown VDiff action '${action}' — check usage before invoking`)
}

Type guard

function isKnownAction(a) {
  return typeof a === "string" && ["show", "stop", "resume", "delete"].includes(a)
}

Try / catch

try {
  runVDiff(`-- ${ks}.${wf} ${action} ${arg}`)
} catch (e) {
  if (String(e).includes("invalid action")) {
    runVDiff("--help")
  } else throw e
}

Prevention

When it happens

Trigger: Same as 1033: invoking VDiff with an action name outside the recognized set; also reachable if a case falls through without returning so control reaches the trailing default.

Common situations: Misspelled action verbs; scripts built against an older Vitess version whose action names changed; automation sending literal placeholders like `<action>`.

Related errors


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

Appendix: source

Thrown at go/vt/vtctl/vdiff2.go:217

		} else {
			displayVDiff2ScheduledResponse(wr, format, vdiffUUID.String(), action)
		}
	case vdiff.ShowAction:
		if output == nil {
			// should not happen
			return errors.New("invalid (empty) response from show command")
		}
		if err := displayVDiff2ShowResponse(wr, format, keyspace, workflowName, actionArg, output, *verbose); err != nil {
			return err
		}
	case vdiff.StopAction, vdiff.DeleteAction:
		uuidToDisplay := ""
		if actionArg != vdiff.AllActionArg {
			uuidToDisplay = vdiffUUID.String()
		}
		displayVDiff2ActionStatusResponse(wr, format, uuidToDisplay, action, vdiff.CompletedState)
	default:
		return fmt.Errorf("invalid action %s; %s", action, usage)
	}

	return nil
}

// region ****show response

// summary aggregates/selects the current state of the vdiff from all shards

type vdiffTableSummary struct {
	TableName       string
	State           vdiff.VDiffState
	RowsCompared    int64
	MatchingRows    int64
	MismatchedRows  int64
	ExtraRowsSource int64
	ExtraRowsTarget int64
	LastUpdated     string `json:"LastUpdated,omitempty"`

View on GitHub (pinned to 01a25a7d17)