{"record":{"id":"12976f44cb0069f8","repo":"vitessio/vitess","slug":"invalid-workflow","errorCode":null,"errorMessage":"invalid workflow","messagePattern":"invalid workflow","errorType":"error_code","errorClass":"ErrInvalidWorkflow","httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/workflow/server.go","lineNumber":118,"sourceCode":"const (\n\tcannotSwitchError               = \"workflow has errors\"\n\tcannotSwitchCopyIncomplete      = \"copy is still in progress\"\n\tcannotSwitchHighLag             = \"replication lag %ds is higher than allowed lag %ds\"\n\tcannotSwitchFailedTabletRefresh = \"could not refresh all of the tablets involved in the operation:\\n%s\"\n\tcannotSwitchFrozen              = \"workflow is frozen\"\n\n\t// Number of LOCK TABLES cycles to perform on the sources during SwitchWrites.\n\tlockTablesCycles = 2\n\t// Time to wait between LOCK TABLES cycles on the sources during SwitchWrites.\n\tlockTablesCycleDelay = time.Duration(100 * time.Millisecond)\n\n\tSqlUnfreezeWorkflow = \"update _vt.vreplication set state='Running', message='' where db_name=%a and workflow=%a\"\n)\n\nvar (\n\t// ErrInvalidWorkflow is a catchall error type for conditions that should be\n\t// impossible when operating on a workflow.\n\tErrInvalidWorkflow = errors.New(\"invalid workflow\")\n\t// ErrMultipleSourceKeyspaces occurs when a workflow somehow has multiple\n\t// source keyspaces across different shard primaries. This should be\n\t// impossible.\n\tErrMultipleSourceKeyspaces = errors.New(\"multiple source keyspaces for a single workflow\")\n\t// ErrMultipleTargetKeyspaces occurs when a workflow somehow has multiple\n\t// target keyspaces across different shard primaries. This should be\n\t// impossible.\n\tErrMultipleTargetKeyspaces          = errors.New(\"multiple target keyspaces for a single workflow\")\n\tErrWorkflowCompleteNotFullySwitched = errors.New(\"cannot complete workflow because you have not yet switched all read and write traffic\")\n\tErrWorkflowDeleteWritesSwitched     = errors.New(\"cannot delete workflow because you have already switched write traffic\")\n)\n\n// Server provides an API to work with Vitess workflows, like vreplication\n// workflows (MoveTables, Reshard, etc) and schema migration workflows.\ntype Server struct {\n\tts  *topo.Server\n\ttmc tmclient.TabletManagerClient\n\t// Limit the number of concurrent background goroutines if needed.","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/workflow/server.go#L100-L136","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nerr := server.WorkflowDelete(ctx, targetKeyspace, workflow, false) // ErrInvalidWorkflow\n// after\n_, err := server.GetWorkflowInfo(ctx, targetKeyspace, workflow)\nif errors.Is(err, workflow.ErrInvalidWorkflow) { /* recreate workflow before deleting */ }","handlingStrategy":"type-guard","validationCode":"n, err := countStreams(keyspace, workflow)\nif err != nil || n == 0 { return workflow.ErrInvalidWorkflow }","typeGuard":"func isInvalidWorkflowErr(err error) bool {\n    return errors.Is(err, workflow.ErrInvalidWorkflow)\n}","tryCatchPattern":"if err := op(ctx, ks, wf); err != nil {\n    if errors.Is(err, workflow.ErrInvalidWorkflow) {\n        // inspect _vt.vreplication and recreate the workflow\n    }\n    return err\n}","preventionTips":["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"],"tags":["vitess","vreplication","workflow","sentinel-error"],"backgroundTag":"invalid-workflow-state","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}