{"record":{"id":"49395f77520b0b59","repo":"vitessio/vitess","slug":"numeric-reversemap-length-of-keyspaceid-is-not-8","errorCode":null,"errorMessage":"Numeric.ReverseMap: length of keyspaceId is not 8: %d","messagePattern":"Numeric\\.ReverseMap: length of keyspaceId is not 8: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/vindexes/numeric.go","lineNumber":104,"sourceCode":"func (vind *Numeric) Map(ctx context.Context, vcursor VCursor, ids []sqltypes.Value) ([]key.ShardDestination, error) {\n\tout := make([]key.ShardDestination, 0, len(ids))\n\tfor _, id := range ids {\n\t\tksid, err := vind.Hash(id)\n\t\tif err != nil {\n\t\t\tout = append(out, key.DestinationNone{})\n\t\t\tcontinue\n\t\t}\n\t\tout = append(out, key.DestinationKeyspaceID(ksid))\n\t}\n\treturn out, nil\n}\n\n// ReverseMap returns the associated ids for the ksids.\nfunc (*Numeric) ReverseMap(_ VCursor, ksids [][]byte) ([]sqltypes.Value, error) {\n\treverseIds := make([]sqltypes.Value, len(ksids))\n\tfor i, keyspaceID := range ksids {\n\t\tif len(keyspaceID) != 8 {\n\t\t\treturn nil, fmt.Errorf(\"Numeric.ReverseMap: length of keyspaceId is not 8: %d\", len(keyspaceID))\n\t\t}\n\t\tval := binary.BigEndian.Uint64(keyspaceID)\n\t\treverseIds[i] = sqltypes.NewUint64(val)\n\t}\n\treturn reverseIds, nil\n}\n\n// RangeMap implements Between.\nfunc (vind *Numeric) 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)}}","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/vindexes/numeric.go#L86-L122","documentation":"Numeric.ReverseMap expects every keyspace id to be exactly 8 bytes (a big-endian uint64). Any shorter/longer id means the keyspace id was not produced by the Numeric vindex, so it cannot be reversed to its numeric id. This usually signals the wrong vindex type is associated with the table or corrupted mapping data.","triggerScenarios":"Calling ReverseMap on a Numeric vindex with a keyspace id whose length != 8, e.g. during vindex reversal workflows (MoveTables/Reshard reverse lookup) when the mapping table contains ids generated by a different vindex (Binary, Hash produce 8 bytes too, but BinaryMD5 produces 16).","commonSituations":"Table was migrated from another vindex type (e.g. binary_md5) but the vschema now claims numeric; lookup/reverse workflow fed with mixed-length keyspace ids; manually crafted keyspace ids in test code.","solutions":["Confirm the vindex type in the vschema matches the one that generated the keyspace ids (numeric -> 8 bytes).","If the table used a different vindex (e.g. binary_md5, 16 bytes), use that vindex type for reversal.","Rebuild the mapping/lookup data with the correct vindex before running reverse workflows."],"exampleFix":"// before (vschema)\n\"vindex\": {\"type\": \"numeric\"}  // but keys are 16-byte md5\n// after\n\"vindex\": {\"type\": \"binary_md5\"}","handlingStrategy":"validation","validationCode":"for _, ksid := range ksids {\n    if len(ksid) != 8 {\n        return errors.New(\"keyspace ids are not from a Numeric vindex\")\n    }\n}","typeGuard":"func isNumericKeyspaceID(k []byte) bool { return len(k) == 8 }","tryCatchPattern":null,"preventionTips":["Use the same vindex type for a table across its entire lifecycle.","Check keyspace-id length (8 for numeric) when migrating vindex types.","Rebuild reverse lookup data with the correct vindex before reversal workflows."],"tags":["vindex","numeric","reverse-map","keyspace-id"],"backgroundTag":"invalid-keyspace-id","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}