{"record":{"id":"da6a767426f92567","repo":"vitessio/vitess","slug":"unexpected-in-keyrange-parameter-v","errorCode":null,"errorMessage":"unexpected in_keyrange parameter: %v","messagePattern":"unexpected in_keyrange parameter: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/tabletserver/vstreamer/planbuilder.go","lineNumber":1017,"sourceCode":"\t\tkrExpr = exprs[len(exprs)-1]\n\tdefault:\n\t\treturn vterrors.Errorf(vtrpcpb.Code_INTERNAL, \"[BUG] unexpected in_keyrange parameters: %v\", sqlparser.SliceString(exprs))\n\t}\n\tvar err error\n\twhereFilter.VindexColumns, err = buildVindexColumns(plan.Table, colnames)\n\tif err != nil {\n\t\treturn err\n\t}\n\tkr, err := selString(krExpr)\n\tif err != nil {\n\t\treturn err\n\t}\n\tkeyranges, err := key.ParseShardingSpec(kr)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif len(keyranges) != 1 {\n\t\treturn fmt.Errorf(\"unexpected in_keyrange parameter: %v\", sqlparser.String(krExpr))\n\t}\n\twhereFilter.KeyRange = keyranges[0]\n\tplan.Filters = append(plan.Filters, whereFilter)\n\treturn nil\n}\n\nfunc selString(expr sqlparser.Expr) (string, error) {\n\tval, ok := expr.(*sqlparser.Literal)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"unsupported: %v\", sqlparser.String(expr))\n\t}\n\treturn val.Val, nil\n}\n\n// buildVindexColumns builds the list of column numbers of the table\n// that will be the input to the vindex function.\nfunc buildVindexColumns(ti *Table, colnames []sqlparser.IdentifierCI) ([]int, error) {\n\tvindexColumns := make([]int, 0, len(colnames))","sourceCodeStart":999,"sourceCodeEnd":1035,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go#L999-L1035","documentation":"analyzeInKeyRange parses the keyrange string argument of in_keyrange() with key.ParseShardingSpec and requires the spec to yield exactly one keyrange. A parameter that parses into zero or multiple ranges (e.g. an empty spec or an 'a-b,c-d' style multi-part spec) is rejected as unexpected for the single-filter in_keyrange form.","triggerScenarios":"Calling VStreamResults with a predicate like `in_keyrange('-80,e0-')` (multi-range spec) or an empty/blank literal that parses to len(keyranges) != 1.","commonSituations":"Copy-pasting multi-range sharding specs from a VReplication filter config into an in_keyrange() predicate; typos like trailing commas creating multiple ranges; assuming in_keyrange accepts the same specs as Filter rules.","solutions":["Pass a single keyrange literal, e.g. in_keyrange('-80') or in_keyrange('80-').","Split multi-range streaming into one VStreamResults request per keyrange.","Validate the string with key.ParseShardingSpec semantics before sending the query.","Use the alternate form in_keyrange(col, 'hash', '-80') if a single column keyrange is what you meant."],"exampleFix":"// before\nselect ... from t where in_keyrange('-80,c0-')\n// after\nselect ... from t where in_keyrange('-80') -- one request per range","handlingStrategy":"validation","validationCode":"// ensure the keyrange string parses to exactly one range before building the query\nkeyranges, err := key.ParseShardingSpec(kr)\nif err != nil || len(keyranges) != 1 {\n    return fmt.Errorf(\"in_keyrange requires exactly one keyrange, got %q\", kr)\n}","typeGuard":"func isSingleKeyRange(kr string) bool {\n    krs, err := key.ParseShardingSpec(kr)\n    return err == nil && len(krs) == 1\n}","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"unexpected in_keyrange parameter\") {\n    return fmt.Errorf(\"split multi-range specs into one in_keyrange() per request: %w\", err)\n}","preventionTips":["Always pass a single-range literal like '-80' or '80-'","Issue one stream per keyrange instead of multi-range specs","Don't reuse multi-part VReplication Filter specs in in_keyrange()"],"tags":["vstreamer","in-keyrange","keyrange","sharding"],"backgroundTag":"invalid-keyrange-spec","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}