vitessio/vitess · error
unexpected in_keyrange parameter: %v
Error message
unexpected in_keyrange parameter: %v
What it means
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.
Source
Thrown at go/vt/vttablet/tabletserver/vstreamer/planbuilder.go:1017
krExpr = exprs[len(exprs)-1]
default:
return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] unexpected in_keyrange parameters: %v", sqlparser.SliceString(exprs))
}
var err error
whereFilter.VindexColumns, err = buildVindexColumns(plan.Table, colnames)
if err != nil {
return err
}
kr, err := selString(krExpr)
if err != nil {
return err
}
keyranges, err := key.ParseShardingSpec(kr)
if err != nil {
return err
}
if len(keyranges) != 1 {
return fmt.Errorf("unexpected in_keyrange parameter: %v", sqlparser.String(krExpr))
}
whereFilter.KeyRange = keyranges[0]
plan.Filters = append(plan.Filters, whereFilter)
return nil
}
func selString(expr sqlparser.Expr) (string, error) {
val, ok := expr.(*sqlparser.Literal)
if !ok {
return "", fmt.Errorf("unsupported: %v", sqlparser.String(expr))
}
return val.Val, nil
}
// buildVindexColumns builds the list of column numbers of the table
// that will be the input to the vindex function.
func buildVindexColumns(ti *Table, colnames []sqlparser.IdentifierCI) ([]int, error) {
vindexColumns := make([]int, 0, len(colnames))View on GitHub (pinned to 01a25a7d17)
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.
Example fix
// before
select ... from t where in_keyrange('-80,c0-')
// after
select ... from t where in_keyrange('-80') -- one request per range Defensive patterns
Strategy: validation
Validate before calling
// ensure the keyrange string parses to exactly one range before building the query
keyranges, err := key.ParseShardingSpec(kr)
if err != nil || len(keyranges) != 1 {
return fmt.Errorf("in_keyrange requires exactly one keyrange, got %q", kr)
} Type guard
func isSingleKeyRange(kr string) bool {
krs, err := key.ParseShardingSpec(kr)
return err == nil && len(krs) == 1
} Try / catch
if err != nil && strings.Contains(err.Error(), "unexpected in_keyrange parameter") {
return fmt.Errorf("split multi-range specs into one in_keyrange() per request: %w", err)
} Prevention
- 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()
When it happens
Trigger: Calling VStreamResults with a predicate like `in_keyrange('-80,e0-')` (multi-range spec) or an empty/blank literal that parses to len(keyranges) != 1.
Common situations: 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.
Related errors
- non-contiguous KeyRange values for %v in cell %v at shard %v
- either source or target shards are missing
- VStreamer is not open
- only integer literals are supported
- only the integer literal 1 is supported
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/da6a767426f92567.
Report an issue: GitHub.