{"record":{"id":"91793f52e36c7c53","repo":"vitessio/vitess","slug":"vreplication-streams-must-have-named-workflows-for-91793f","errorCode":null,"errorMessage":"VReplication streams must have named workflows for migration: shard: %s:%s","messagePattern":"VReplication streams must have named workflows for migration: shard: (.+?):(.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/wrangler/resharder.go","lineNumber":216,"sourceCode":"\t\tmu.Lock()\n\t\tdefer mu.Unlock()\n\n\t\tmustCreate := false\n\t\tvar ref map[string]bool\n\t\tif rs.refStreams == nil {\n\t\t\trs.refStreams = make(map[string]*refStream)\n\t\t\tmustCreate = true\n\t\t} else {\n\t\t\t// Copy the ref streams for comparison.\n\t\t\tref = make(map[string]bool, len(rs.refStreams))\n\t\t\tfor k := range rs.refStreams {\n\t\t\t\tref[k] = true\n\t\t\t}\n\t\t}\n\t\tfor _, row := range qr.Rows {\n\t\t\tworkflow := row[0].ToString()\n\t\t\tif workflow == \"\" {\n\t\t\t\treturn fmt.Errorf(\"VReplication streams must have named workflows for migration: shard: %s:%s\", source.Keyspace(), source.ShardName())\n\t\t\t}\n\t\t\tvar bls binlogdatapb.BinlogSource\n\t\t\trowBytes, err := row[1].ToBytes()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := prototext.Unmarshal(rowBytes, &bls); err != nil {\n\t\t\t\treturn vterrors.Wrapf(err, \"prototext.Unmarshal: %v\", row)\n\t\t\t}\n\t\t\tisReference, err := rs.blsIsReference(&bls)\n\t\t\tif err != nil {\n\t\t\t\treturn vterrors.Wrap(err, \"blsIsReference\")\n\t\t\t}\n\t\t\tif !isReference {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tkey := fmt.Sprintf(\"%s:%s:%s\", workflow, bls.Keyspace, bls.Shard)\n\t\t\tif mustCreate {","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/wrangler/resharder.go#L198-L234","documentation":"When preparing to migrate VReplication streams during a reshard, each stream row read from `_vt.vreplication` must have a non-empty workflow name so it can be re-created on the target shards. Older Vitess versions allowed anonymous streams; such a stream makes migration impossible, so the code errors with the offending shard.","triggerScenarios":"Resharding (or any workflow that migrates streams) when a source shard's `_vt.vreplication` table contains a row with an empty `workflow` column — typically a stream created on an older Vitess version before workflows were mandatory.","commonSituations":"Cluster upgraded from a pre-workflow Vitess release with legacy continuous filter streams left running; a manually inserted vreplication row for testing without a workflow name; half-deleted migration that left an unnamed stream behind.","solutions":["Find the offending row: `SELECT rid, workflow FROM _vt.vreplication;` on the source shard's primary via vtctldtablet or direct MySQL on the _vt schema.","Give the stream a name (`UPDATE _vt.vreplication SET workflow='<name>' WHERE rid=<id>`) or delete it if it is obsolete (`DELETE FROM _vt.vreplication WHERE rid=<id>`).","Prefer deleting stale legacy streams and recreating them with a named workflow (e.g. via MoveTables/Reshard) if the tooling allows.","Re-run the reshard once no empty-workflow rows remain on any source shard."],"exampleFix":"-- before\nSELECT rid, workflow FROM _vt.vreplication; -- rid=1, workflow=''\nUPDATE _vt.vreplication SET workflow='legacy_filter' WHERE rid=1;\n-- after\nSELECT rid, workflow FROM _vt.vreplication; -- rid=1, workflow='legacy_filter'","handlingStrategy":"validation","validationCode":"qr, _ := querySourcePrimary(\"SELECT rid, workflow FROM _vt.vreplication\")\nfor _, row := range qr.Rows {\n    if row[1].ToString() == \"\" {\n        return fmt.Errorf(\"unnamed vreplication stream rid=%s; name or delete before reshard\", row[0].ToString())\n    }\n}","typeGuard":"func hasNamedWorkflows(rows []sqltypes.Row) bool {\n    for _, r := range rows { if r[1].ToString() == \"\" { return false } }\n    return true\n}","tryCatchPattern":"if err := wr.Reshard(...); err != nil {\n    if strings.Contains(err.Error(), \"must have named workflows\") {\n        return fixUnnamedStreamsThenRetry(ctx, source)\n    }\n    return err\n}","preventionTips":["Upgrade legacy anonymous streams after version upgrades by naming or deleting them","Never hand-insert rows into _vt.vreplication without a workflow name","Audit _vt.vreplication for empty workflow values as a scheduled check"],"tags":["vreplication","workflow","reshard","migration"],"backgroundTag":"unnamed-vreplication-workflow","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}