{"record":{"id":"c96100640680d9b3","repo":"vitessio/vitess","slug":"multiple-target-keyspaces-for-a-single-workflow","errorCode":null,"errorMessage":"multiple target keyspaces for a single workflow","messagePattern":"multiple target keyspaces for a single workflow","errorType":"error_code","errorClass":"ErrMultipleTargetKeyspaces","httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/workflow/server.go","lineNumber":126,"sourceCode":"\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.\n\tsem     *semaphore.Weighted\n\tenv     *vtenv.Environment\n\toptions serverOptions\n}\n\n// NewServer returns a new server instance with the given topo.Server and\n// TabletManagerClient.\nfunc NewServer(env *vtenv.Environment, ts *topo.Server, tmc tmclient.TabletManagerClient, opts ...ServerOption) *Server {","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/workflow/server.go#L108-L144","documentation":"ErrMultipleTargetKeyspaces is returned by scanWorkflow when a single workflow's streams report multiple target keyspaces across shard primaries. Healthy workflows always replicate into exactly one target keyspace, so this sentinel flags inconsistent workflow metadata.","triggerScenarios":"scanWorkflow encountering _vt.vreplication rows whose specs point at different target keyspaces for the same workflow name.","commonSituations":"Leftover streams from a partially cleaned-up workflow, manual metadata edits, or a workflow name collision across operations that wrote rows into both keyspaces.","solutions":["Query _vt.vreplication on the target shards and identify streams whose target keyspace differs.","Delete the stale/inconsistent streams so only one target keyspace remains.","Recreate the workflow cleanly if reconciliation is not feasible."],"exampleFix":"// before\nstreams targeting keyspaces: customer and customer_new under workflow 'sales' -> error\n// after\ndelete from _vt.vreplication where workflow='sales' and db_name='customer_new';\n// workflow now has a single target keyspace","handlingStrategy":"type-guard","validationCode":"targets := distinctTargetKeyspaces(keyspace, workflow)\nif len(targets) > 1 { return workflow.ErrMultipleTargetKeyspaces }","typeGuard":"func isMultipleTargetKeyspaces(err error) bool {\n    return errors.Is(err, workflow.ErrMultipleTargetKeyspaces)\n}","tryCatchPattern":"if err := op(ctx, ks, wf); err != nil {\n    if errors.Is(err, workflow.ErrMultipleTargetKeyspaces) {\n        // clean up stale streams in the extra target keyspace\n    }\n    return err\n}","preventionTips":["Use unique workflow names per migration","Delete stale streams from cancelled workflows","Audit target keyspace consistency after partial cutovers"],"tags":["vitess","vreplication","workflow","corrupt-metadata"],"backgroundTag":"invalid-workflow-state","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}