{"record":{"id":"f35659799432fc97","repo":"redis/go-redis","slug":"redis-collect-value-has-type-t-want-array-of-en","errorCode":null,"errorMessage":"redis: COLLECT value has type %T, want array of entries","messagePattern":"redis: COLLECT value has type %T, want array of entries","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"search_collect.go","lineNumber":192,"sourceCode":"// preserved as returned by the server; it is meaningful only when the COLLECT\n// reducer was given a SORTBY.\nfunc (r AggregateRow) Collect(alias string) (CollectColumn, error) {\n\tv, ok := r.Fields[alias]\n\tif !ok {\n\t\treturn nil, nil\n\t}\n\treturn parseCollectValue(v)\n}\n\n// parseCollectValue decodes a raw COLLECT alias value (an array of entries)\n// into a CollectColumn.\nfunc parseCollectValue(v interface{}) (CollectColumn, error) {\n\tif v == nil {\n\t\treturn nil, nil\n\t}\n\tarr, ok := v.([]interface{})\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"redis: COLLECT value has type %T, want array of entries\", v)\n\t}\n\tout := make(CollectColumn, 0, len(arr))\n\tfor i, e := range arr {\n\t\tentry, err := parseCollectEntry(e)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"redis: COLLECT entry %d: %w\", i, err)\n\t\t}\n\t\tout = append(out, entry)\n\t}\n\treturn out, nil\n}\n\n// parseCollectEntry decodes a single collected entry from either the RESP3\n// map form or the RESP2 flat key/value array form into a CollectEntry. Keys\n// are passed through as-is: the server already returns them without the \"@\"\n// prefix.\nfunc parseCollectEntry(e interface{}) (CollectEntry, error) {\n\tswitch m := e.(type) {","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/redis/go-redis/blob/c5cad058c72f58370553b48566302303cf8a2e89/search_collect.go#L174-L210","documentation":"After FT.AGGREGATE runs with a COLLECT step, parseCollectValue expects the server's COLLECT reply value to be a RESP array ([]interface{}) of entries. Any other Go type means the reply shape is not what this client expects, so parsing fails with this error.","triggerScenarios":"Calling Collect on a result whose COLLECT value decoded to a non-array type — e.g. RESP2/RESP3 mismatch, a proxy or module version returning a scalar, or binding the wrong command's reply.","commonSituations":"Running through a RESP proxy that reshapes replies; a server/RediSearch version returning a different COLLECT encoding; misuse of the API reading a non-aggregate reply.","solutions":["Ensure the Redis server/RediSearch version returns the expected COLLECT array encoding","Use RESP3 (Protocol: 3) if the COLLECT reply shape differs under RESP2","Verify you are reading the COLLECT value from the FT.AGGREGATE reply, not another command's"],"exampleFix":"// before\ncol, err := cmd.Collect() // scalar reply from an older server/proxy\n// after\nopt := redis.Options{Protocol: 3} // ensure RESP3 and a supported server version\n// then\ncol, err := cmd.Collect()","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isCollectArray(v interface{}) bool {\n    _, ok := v.([]interface{})\n    return ok\n}","tryCatchPattern":"col, err := cmd.Collect()\nif err != nil {\n    log.Fatalf(\"COLLECT parse failed: %v\", err) // message includes actual %T\n}","preventionTips":["Pin and test against a known RediSearch/server version","Enable RESP3 for aggregate queries","Log the raw reply type (%T) when parsing fails"],"tags":["search","ft-aggregate","collect","reply-parsing","resp"],"backgroundTag":"unexpected-reply-shape","analyzedSha":"c5cad058c72f58370553b48566302303cf8a2e89","analyzedAt":"2026-09-01T06:50:53.388Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}