{"record":{"id":"c435dd448f509fee","repo":"vitessio/vitess","slug":"cannot-reshard-streams-with-a-mix-of-reference-and-c435dd","errorCode":null,"errorMessage":"cannot reshard streams with a mix of reference and sharded tables: %v","messagePattern":"cannot reshard streams with a mix of reference and sharded tables: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/wrangler/resharder.go","lineNumber":269,"sourceCode":"\t\treturn nil\n\t})\n\treturn err\n}\n\n// blsIsReference is partially copied from streamMigrater.templatize.\n// It reuses the constants from that function also.\nfunc (rs *resharder) blsIsReference(bls *binlogdatapb.BinlogSource) (bool, error) {\n\tstreamType := workflow.StreamTypeUnknown\n\tfor _, rule := range bls.Filter.Rules {\n\t\ttyp, err := rs.identifyRuleType(rule)\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\n\t\tswitch typ {\n\t\tcase workflow.StreamTypeSharded:\n\t\t\tif streamType == workflow.StreamTypeReference {\n\t\t\t\treturn false, fmt.Errorf(\"cannot reshard streams with a mix of reference and sharded tables: %v\", bls)\n\t\t\t}\n\t\t\tstreamType = workflow.StreamTypeSharded\n\t\tcase workflow.StreamTypeReference:\n\t\t\tif streamType == workflow.StreamTypeSharded {\n\t\t\t\treturn false, fmt.Errorf(\"cannot reshard streams with a mix of reference and sharded tables: %v\", bls)\n\t\t\t}\n\t\t\tstreamType = workflow.StreamTypeReference\n\t\t}\n\t}\n\treturn streamType == workflow.StreamTypeReference, nil\n}\n\nfunc (rs *resharder) identifyRuleType(rule *binlogdatapb.Rule) (workflow.StreamType, error) {\n\tvtable, ok := rs.vschema.Tables[rule.Match]\n\tif !ok && !schema.IsInternalOperationTableName(rule.Match) {\n\t\treturn 0, fmt.Errorf(\"table %v not found in vschema\", rule.Match)\n\t}\n\tif vtable != nil && vtable.Type == vindexes.TypeReference {","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/wrangler/resharder.go#L251-L287","documentation":"blsIsReference determines the stream type (Reference vs Sharded) from the table filters inside a stream's BinlogSource. If different tables (or different streams) resolve to conflicting types — some reference, some sharded — the resharding code cannot handle the mix and errors, printing the offending BinlogSource.","triggerScenarios":"Resharding a keyspace whose VReplication streams' filter rules mix `KeyRange`-sharded table rules with reference-table rules (no keyrange) within the same workflow's streams.","commonSituations":"A workflow was edited over time so some rules became reference tables while others stayed sharded; combining MoveTables output with reference-table streams manually; misconfigured filter JSON where a table intended to be reference got a keyrange assigned.","solutions":["Inspect the stream's filter (print the BinlogSource from `_vt.vreplication`) and identify which rules are KeyRange-based vs reference-style.","Split the workflow: move reference-table streams into a separate workflow/keyspace configuration from the sharded-table streams, then reshard each separately.","Fix the filter rules so all tables in the stream are consistently typed (remove the keyrange on reference tables or drop them from this stream).","Re-run the reshard after the stream configuration is homogeneous."],"exampleFix":"// before: filter mixes rules\n{\"rules\":[{\"match\":\"ref_t\"},{\"match\":\"sharded_t\",\"keyrange\":\"-80\"}]}\n// after: only sharded rules in this stream; move ref_t to a reference stream\n{\"rules\":[{\"match\":\"sharded_t\",\"keyrange\":\"-80\"}]}","handlingStrategy":"validation","validationCode":"for _, rule := range bls.Filter.Rules {\n    isSharded := rule.GetKeyrange() != \"\"\n    if lastSeen != nil && isSharded != *lastSeen {\n        return fmt.Errorf(\"filter mixes reference and sharded tables\")\n    }\n    lastSeen = &isSharded\n}","typeGuard":"func isUniformStreamType(bls *binlogdatapb.BinlogSource) bool {\n    seenSharded, seenRef := false, false\n    for _, r := range bls.Filter.Rules {\n        if r.GetKeyrange() != \"\" { seenSharded = true } else { seenRef = true }\n    }\n    return !(seenSharded && seenRef)\n}","tryCatchPattern":"if err := wr.Reshard(...); err != nil {\n    if strings.Contains(err.Error(), \"mix of reference and sharded tables\") {\n        return splitReferenceAndShardedWorkflows(ctx, bls)\n    }\n    return err\n}","preventionTips":["Keep reference-table streams in dedicated workflows separate from sharded-table streams","Review filter rules for stray keyrange assignments on reference tables","Validate stream type uniformity before initiating a reshard"],"tags":["vreplication","reshard","reference-tables","filter"],"backgroundTag":"mixed-stream-types","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}