{"record":{"id":"4b3e294409e3b1c9","repo":"redis/go-redis","slug":"redis-got-d-elements-in-the-map-wanted-d","errorCode":null,"errorMessage":"redis: got %d elements in the map, wanted %d","messagePattern":"redis: got (.+?) elements in the map, wanted (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/proto/reader.go","lineNumber":742,"sourceCode":"\tif err != nil {\n\t\treturn 0, err\n\t}\n\tswitch line[0] {\n\tcase RespArray, RespSet, RespPush:\n\t\treturn replyLen(line)\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"redis: can't parse array/set/push reply: %.100q\", line)\n\t}\n}\n\n// ReadFixedMapLen reads fixed map length.\nfunc (r *Reader) ReadFixedMapLen(fixedLen int) error {\n\tn, err := r.ReadMapLen()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif n != fixedLen {\n\t\treturn fmt.Errorf(\"redis: got %d elements in the map, wanted %d\", n, fixedLen)\n\t}\n\treturn nil\n}\n\n// ReadMapLen reads the length of the map type.\n// If responding to the array type (RespArray/RespSet/RespPush),\n// it must be a multiple of 2 and return n/2.\n// Other types will return an error.\nfunc (r *Reader) ReadMapLen() (int, error) {\n\tline, err := r.ReadLine()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tswitch line[0] {\n\tcase RespMap:\n\t\treturn replyLen(line)\n\tcase RespArray, RespSet, RespPush:\n\t\t// Some commands and RESP2 protocol may respond to array types.","sourceCodeStart":724,"sourceCodeEnd":760,"githubUrl":"https://github.com/redis/go-redis/blob/c5cad058c72f58370553b48566302303cf8a2e89/internal/proto/reader.go#L724-L760","documentation":"ReadFixedMapLen asserts the reply map has an exact expected number of key-value pairs. The server returned a map (or RESP2 array-as-map) with a different count, breaking the fixed-shape contract used e.g. by readRunningScript, readEngines (FUNCTION/SCRIPT replies). It protects positional key-value decoding from silent misalignment.","triggerScenarios":"Calling ReadFixedMapLen(n) for FUNCTION LIST / SCRIPT related replies when the server returns a different pair count — typically a Redis version difference in FUNCTION/FCALL metadata, or a module (RedisGears engines) reporting a different field set.","commonSituations":"Server upgraded/downgraded between Redis versions with changed reply fields; modules installed or removed changing engine listings; custom proxies altering reply contents.","solutions":["Match the server/RedisGears version to what the parser expects, or upgrade go-redis for new reply shapes","Use ReadMapLen and iterate keys dynamically when the field set can vary","Compare actual reply via redis-cli --raw against the expected fixed length","Avoid mixing Redis versions behind one endpoint during rolling upgrades"],"exampleFix":"// before\nerr := reader.ReadFixedMapLen(3)\n// after: accept variable engine field counts\nn, err := reader.ReadMapLen()\nif err != nil { return err }\nfor i := 0; i < n; i++ { /* read key/value pairs */ }","handlingStrategy":"validation","validationCode":"// confirm expected field count from server before fixed-map parse\n// redis-cli --raw \"FUNCTION LIST\" to count key/value pairs on your version","typeGuard":null,"tryCatchPattern":"err := reader.ReadFixedMapLen(3)\nif err != nil && strings.Contains(err.Error(), \"wanted\") {\n  return fmt.Errorf(\"function/engine reply shape mismatch (server version?): %w\", err)\n}","preventionTips":["Keep Redis/module versions aligned with go-redis expectations","Use ReadMapLen for replies whose field set can vary","Test FUNCTION/FCALL paths after every Redis upgrade","Avoid proxies that drop or add reply fields"],"tags":["go-redis","resp-protocol","map","version-compat"],"backgroundTag":"unexpected-reply-shape","analyzedSha":"c5cad058c72f58370553b48566302303cf8a2e89","analyzedAt":"2026-09-01T06:50:53.388Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}