vitessio/vitess · error

workflow has to be defined for action

Error message

workflow has to be defined for action %s

What it means

WorkflowCommands (Migration/Reshard/MoveTables type operations) requires a workflow name for every action except 'listall'. splitKeyspaceWorkflow succeeded but the workflow part was empty, so the command fails fast with this message.

Solutions

  1. Pass the workflow in the argument: `<keyspace>/<workflow>`
  2. Use `listall` action first to discover workflow names: `vtctldclient Workflow listall commerce`
  3. Fix the calling script to always include the workflow name

Example fix

// before
vtctldclient Workflow status commerce
// after
vtctldclient Workflow status commerce/reshard1
Defensive patterns

Strategy: validation

Validate before calling

keyspace, workflow, err := splitKeyspaceWorkflow(arg)
if err != nil || (action != "listall" && workflow == "") {
	return fmt.Errorf("use <keyspace>/<workflow> for action %s", action)
}

Try / catch

if err := workflowAction(action, arg); err != nil {
	if strings.Contains(err.Error(), "workflow has to be defined") {
		return fmt.Errorf("list workflows first: vtctldclient Workflow listall %s", keyspace)
	}
	return err
}

Prevention

When it happens

Trigger: Running `vtctldclient Workflow <action> <keyspace>` (no /workflow suffix) for any action other than listall, e.g. `vtctldclient Workflow show commerce` instead of `Workflow show commerce/reshard1`.

Common situations: Forgetting the `/workflow` component of the argument; assuming the keyspace has a single implicit workflow; shell scripts stripping the part after a slash.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

		return err
	}
	if subFlags.NArg() < 2 {
		return errors.New(usage)
	}
	if len(*shards) > 0 {
		log.Info(fmt.Sprintf("Subset of shards specified: %d, %v", len(*shards), strings.Join(*shards, ",")))
	}
	keyspace := subFlags.Arg(0)
	action := strings.ToLower(subFlags.Arg(1))
	var workflow string
	var err error
	if action != "listall" {
		keyspace, workflow, err = splitKeyspaceWorkflow(subFlags.Arg(0))
		if err != nil {
			return err
		}
		if workflow == "" {
			return fmt.Errorf("workflow has to be defined for action %s", action)
		}
	}
	_, err = wr.TopoServer().GetKeyspace(ctx, keyspace)
	if err != nil {
		wr.Logger().Errorf("Keyspace %s not found", keyspace)
	}
	var results map[*topo.TabletInfo]*sqltypes.Result
	if action == "tags" {
		tags := ""
		if subFlags.NArg() != 3 {
			return errors.New("tags incorrectly specified, usage: Workflow keyspace.workflow tags <tags>")
		}
		tags = strings.ToLower(subFlags.Arg(2))
		results, err = wr.WorkflowTagAction(ctx, keyspace, workflow, tags)
		if err != nil {
			return err
		}
	} else {

View on GitHub (pinned to 01a25a7d17)