{"record":{"id":"7b1a694a0ed5e285","repo":"vitessio/vitess","slug":"binary-reversemap-keyspaceid-is-nil","errorCode":null,"errorMessage":"Binary.ReverseMap: keyspaceId is nil","messagePattern":"Binary\\.ReverseMap: keyspaceId is nil","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/vindexes/binary.go","lineNumber":105,"sourceCode":"\t\tidBytes, err := vind.Hash(id)\n\t\tif err != nil {\n\t\t\treturn out, err\n\t\t}\n\t\tout = append(out, key.DestinationKeyspaceID(idBytes))\n\t}\n\treturn out, nil\n}\n\nfunc (vind *Binary) Hash(id sqltypes.Value) ([]byte, error) {\n\treturn id.ToBytes()\n}\n\n// ReverseMap returns the associated ids for the ksids.\nfunc (*Binary) ReverseMap(_ VCursor, ksids [][]byte) ([]sqltypes.Value, error) {\n\treverseIds := make([]sqltypes.Value, len(ksids))\n\tfor rownum, keyspaceID := range ksids {\n\t\tif keyspaceID == nil {\n\t\t\treturn nil, errors.New(\"Binary.ReverseMap: keyspaceId is nil\")\n\t\t}\n\t\treverseIds[rownum] = sqltypes.MakeTrusted(sqltypes.VarBinary, keyspaceID)\n\t}\n\treturn reverseIds, nil\n}\n\n// RangeMap can map ids to key.ShardDestination objects.\nfunc (vind *Binary) RangeMap(ctx context.Context, vcursor VCursor, startId sqltypes.Value, endId sqltypes.Value) ([]key.ShardDestination, error) {\n\tstartKsId, err := vind.Hash(startId)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tendKsId, err := vind.Hash(endId)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tout := []key.ShardDestination{&key.DestinationKeyRange{KeyRange: key.NewKeyRange(startKsId, endKsId)}}\n\treturn out, nil","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/vindexes/binary.go#L87-L123","documentation":"Returned by Binary.ReverseMap when the input keyspaceId is nil. The binary vindex requires a non-nil keyspace ID to reverse-map back to the source value; nil input indicates an upstream mapping bug or corrupted data.","triggerScenarios":"Calling ReverseMap on a Binary vindex with a [][]byte containing at least one nil entry — typically from a lookup/routing path where the keyspace ID was never populated.","commonSituations":"Routing queries through vindexes with incomplete routing data; bugs in custom code or callers constructing VCursor requests with missing ksids.","solutions":["Ensure all keyspace IDs passed to ReverseMap are non-nil","Check upstream code that builds the ksids slice for a path that leaves entries nil","Use a Owned/lookup vindex flow that always produces valid keyspace IDs for existing rows"],"exampleFix":"// before\nksids := [][]byte{nil}\nvals, err := vindex.ReverseMap(ctx, vcursor, ksids)\n// after\nksids := [][]byte{[]byte(\"\\x80\\x00\")}\nvals, err := vindex.ReverseMap(ctx, vcursor, ksids)","handlingStrategy":"validation","validationCode":"for i, ksid := range ksids {\n    if ksid == nil {\n        return fmt.Errorf(\"ksid[%d] is nil before ReverseMap\", i)\n    }\n}","typeGuard":null,"tryCatchPattern":"vals, err := vindex.ReverseMap(ctx, vcursor, ksids)\nif err != nil && strings.Contains(err.Error(), \"keyspaceId is nil\") {\n    // inspect upstream routing data construction\n}","preventionTips":["Never insert nil into [][]byte keyspace ID slices","Assert keyspace IDs are non-nil where they are produced","Add table-driven tests covering nil ksid inputs to custom vindexes"],"tags":["vindex","vtgate","nil-value"],"backgroundTag":"nil-keyspace-id","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}