vitessio/vitess · error · ErrInvalidWorkflow
invalid workflow
Error message
invalid workflow
What it means
ErrInvalidWorkflow is a catchall sentinel for conditions that should be impossible when operating on a workflow in the workflow server. It is returned when internal invariants of a vreplication workflow are violated, e.g. the workflow's stored state cannot be reconciled with what the API expects. Because it is a sentinel, callers can compare with errors.Is.
Source
Thrown at go/vt/vtctl/workflow/server.go:118
const (
cannotSwitchError = "workflow has errors"
cannotSwitchCopyIncomplete = "copy is still in progress"
cannotSwitchHighLag = "replication lag %ds is higher than allowed lag %ds"
cannotSwitchFailedTabletRefresh = "could not refresh all of the tablets involved in the operation:\n%s"
cannotSwitchFrozen = "workflow is frozen"
// Number of LOCK TABLES cycles to perform on the sources during SwitchWrites.
lockTablesCycles = 2
// Time to wait between LOCK TABLES cycles on the sources during SwitchWrites.
lockTablesCycleDelay = time.Duration(100 * time.Millisecond)
SqlUnfreezeWorkflow = "update _vt.vreplication set state='Running', message='' where db_name=%a and workflow=%a"
)
var (
// ErrInvalidWorkflow is a catchall error type for conditions that should be
// impossible when operating on a workflow.
ErrInvalidWorkflow = errors.New("invalid workflow")
// ErrMultipleSourceKeyspaces occurs when a workflow somehow has multiple
// source keyspaces across different shard primaries. This should be
// impossible.
ErrMultipleSourceKeyspaces = errors.New("multiple source keyspaces for a single workflow")
// ErrMultipleTargetKeyspaces occurs when a workflow somehow has multiple
// target keyspaces across different shard primaries. This should be
// impossible.
ErrMultipleTargetKeyspaces = errors.New("multiple target keyspaces for a single workflow")
ErrWorkflowCompleteNotFullySwitched = errors.New("cannot complete workflow because you have not yet switched all read and write traffic")
ErrWorkflowDeleteWritesSwitched = errors.New("cannot delete workflow because you have already switched write traffic")
)
// Server provides an API to work with Vitess workflows, like vreplication
// workflows (MoveTables, Reshard, etc) and schema migration workflows.
type Server struct {
ts *topo.Server
tmc tmclient.TabletManagerClient
// Limit the number of concurrent background goroutines if needed.View on GitHub (pinned to 01a25a7d17)
Solutions
- Verify the workflow name and keyspace are correct with `Workflow Show` / query `select * from _vt.vreplication where workflow='...'`.
- Delete the broken workflow rows and recreate the workflow (MoveTables/Reshard) from scratch.
- If the workflow should be valid, inspect vtctld logs for the underlying invariant failure and repair the specific inconsistent stream rows.
Example fix
// before
err := server.WorkflowDelete(ctx, targetKeyspace, workflow, false) // ErrInvalidWorkflow
// after
_, err := server.GetWorkflowInfo(ctx, targetKeyspace, workflow)
if errors.Is(err, workflow.ErrInvalidWorkflow) { /* recreate workflow before deleting */ } Defensive patterns
Strategy: type-guard
Validate before calling
n, err := countStreams(keyspace, workflow)
if err != nil || n == 0 { return workflow.ErrInvalidWorkflow } Type guard
func isInvalidWorkflowErr(err error) bool {
return errors.Is(err, workflow.ErrInvalidWorkflow)
} Try / catch
if err := op(ctx, ks, wf); err != nil {
if errors.Is(err, workflow.ErrInvalidWorkflow) {
// inspect _vt.vreplication and recreate the workflow
}
return err
} Prevention
- Verify the workflow exists with Workflow Show before mutating it
- Avoid manual edits to _vt.vreplication rows
- Use errors.Is against the sentinel rather than string matching
When it happens
Trigger: Calling workflow server operations (e.g. MoveTablesComplete, WorkflowDelete, state-scanning helpers) on a workflow whose persisted _vt.vreplication rows are missing, malformed, or inconsistent, so the server cannot build a coherent workflow object.
Common situations: Corrupted or partially deleted vreplication metadata after a failed migration, operating on a workflow in the wrong keyspace, or version-mismatched vtctld reading older schema-migration rows.
Related errors
- both atomic copy and partial mode cannot be specified for th
- multiple source keyspaces for a single workflow
- multiple target keyspaces for a single workflow
- value out of range
- no streams found
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/12976f44cb0069f8.
Report an issue: GitHub.