{"record":{"id":"726f9f4373903b2b","repo":"vitessio/vitess","slug":"vreplication-streams-must-have-named-workflows-for-726f9f","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":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/workflow/stream_migrator.go","lineNumber":393,"sourceCode":"func (sm *StreamMigrator) readTabletStreams(ctx context.Context, ti *topo.TabletInfo, ids []int32, states []binlogdatapb.VReplicationWorkflowState, excludeFrozen bool) ([]*VReplicationStream, error) {\n\treq := &tabletmanagerdatapb.ReadVReplicationWorkflowsRequest{\n\t\tExcludeWorkflows: []string{sm.ts.ReverseWorkflowName()},\n\t\tIncludeIds:       ids,\n\t\tIncludeStates:    states,\n\t\tExcludeFrozen:    excludeFrozen,\n\t}\n\n\tres, err := sm.ts.TabletManagerClient().ReadVReplicationWorkflows(ctx, ti.Tablet, req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttabletStreams := make([]*VReplicationStream, 0, len(res.Workflows))\n\n\tfor _, workflow := range res.Workflows {\n\t\tswitch workflow.Workflow {\n\t\tcase \"\":\n\t\t\treturn nil, fmt.Errorf(\"VReplication streams must have named workflows for migration: shard: %s:%s\",\n\t\t\t\tti.Keyspace, ti.Shard)\n\t\tcase sm.ts.WorkflowName():\n\t\t\treturn nil, fmt.Errorf(\"VReplication stream has the same workflow name as the resharding workflow: shard: %s:%s\",\n\t\t\t\tti.Keyspace, ti.Shard)\n\t\t}\n\n\t\tfor _, stream := range workflow.Streams {\n\t\t\tisReference, err := sm.blsIsReference(stream.Bls)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, vterrors.Wrap(err, \"blsIsReference\")\n\t\t\t}\n\n\t\t\tif isReference {\n\t\t\t\tsm.ts.Logger().Infof(\"readTabletStreams: ignoring reference table %+v\", stream.Bls)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tpos, err := replication.DecodePosition(stream.Pos)","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/workflow/stream_migrator.go#L375-L411","documentation":"Thrown by readTabletStreams (the non-legacy, ReadVReplicationWorkflows-based path) when a workflow returned from the tablet has an empty name. The stream migrator only supports migrating named VReplication workflows; unnamed streams cannot be tracked, stopped, or recreated on the target shards, so the operation aborts.","triggerScenarios":"Calling stream migration (MigrateStreams / MoveTables stream transfer) against a source shard primary whose _vt.vreplication rows (as surfaced by ReadVReplicationWorkflows) contain a workflow with an empty Workflow string.","commonSituations":"Streams created by very old Vitess versions or manual INSERTs into _vt.vreplication without a workflow value; legacy one-off streams predating mandatory workflow names; mixed-version clusters where the tabletmanager returns unnamed rows.","solutions":["Identify the unnamed stream: `select id, workflow from _vt.vreplication` on the source shard primary and find rows with empty workflow.","Name the stream explicitly (`update _vt.vreplication set workflow='<descriptive-name>' where id=<id>`) and rerun the migration.","If the stream is obsolete, remove it via vtctldclient Workflow Remove or a DELETE on _vt.vreplication.","Upgrade tablets to a Vitess version that always populates workflow names, then retry."],"exampleFix":"// before\nmysql> update _vt.vreplication set id=7 where ...; -- row has workflow=''\n// after\nmysql> update _vt.vreplication set workflow='legacy_kd_copy' where id=7;","handlingStrategy":"validation","validationCode":"rows, _ := qr.Rows // select id, workflow from _vt.vreplication\nfor _, r := range rows {\n    if r[\"workflow\"].ToString() == \"\" {\n        return fmt.Errorf(\"stream %d has no workflow name; name or delete it before migrating\", id)\n    }\n}","typeGuard":"func hasWorkflowName(workflow string) bool {\n    return strings.TrimSpace(workflow) != \"\"\n}","tryCatchPattern":"if err := migrateStreams(ctx, cfg); err != nil && strings.Contains(err.Error(), \"must have named workflows\") {\n    // locate unnamed stream in _vt.vreplication, name or remove it, retry\n}","preventionTips":["Upgrade to a Vitess version that always records workflow names","Audit for empty workflow columns before migrations","Avoid direct INSERTs into _vt.vreplication"],"tags":["vitess","vreplication","workflow-migration","data-validation"],"backgroundTag":"unnamed-vreplication-workflow","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}