redis/go-redis · error
redis: COLLECT value has type %T, want array of entries
Error message
redis: COLLECT value has type %T, want array of entries
What it means
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.
Source
Thrown at search_collect.go:192
// preserved as returned by the server; it is meaningful only when the COLLECT
// reducer was given a SORTBY.
func (r AggregateRow) Collect(alias string) (CollectColumn, error) {
v, ok := r.Fields[alias]
if !ok {
return nil, nil
}
return parseCollectValue(v)
}
// parseCollectValue decodes a raw COLLECT alias value (an array of entries)
// into a CollectColumn.
func parseCollectValue(v interface{}) (CollectColumn, error) {
if v == nil {
return nil, nil
}
arr, ok := v.([]interface{})
if !ok {
return nil, fmt.Errorf("redis: COLLECT value has type %T, want array of entries", v)
}
out := make(CollectColumn, 0, len(arr))
for i, e := range arr {
entry, err := parseCollectEntry(e)
if err != nil {
return nil, fmt.Errorf("redis: COLLECT entry %d: %w", i, err)
}
out = append(out, entry)
}
return out, nil
}
// parseCollectEntry decodes a single collected entry from either the RESP3
// map form or the RESP2 flat key/value array form into a CollectEntry. Keys
// are passed through as-is: the server already returns them without the "@"
// prefix.
func parseCollectEntry(e interface{}) (CollectEntry, error) {
switch m := e.(type) {View on GitHub (pinned to c5cad058c7)
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
Example fix
// before
col, err := cmd.Collect() // scalar reply from an older server/proxy
// after
opt := redis.Options{Protocol: 3} // ensure RESP3 and a supported server version
// then
col, err := cmd.Collect() Defensive patterns
Strategy: type-guard
Type guard
func isCollectArray(v interface{}) bool {
_, ok := v.([]interface{})
return ok
} Try / catch
col, err := cmd.Collect()
if err != nil {
log.Fatalf("COLLECT parse failed: %v", err) // message includes actual %T
} Prevention
- Pin and test against a known RediSearch/server version
- Enable RESP3 for aggregate queries
- Log the raw reply type (%T) when parsing fails
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- redis: COLLECT entry %d: %w
- redis: FT.AGGREGATE COLLECT: empty field name in Fields
- redis: FT.AGGREGATE COLLECT requires FieldsAll or a non-empt
- redis: FT.AGGREGATE COLLECT: empty field name in SortBy
- redis: FT.AGGREGATE COLLECT: ASC and DESC are mutually exclu
AI-assisted analysis of redis/go-redis@c5cad058c7 (2026-09-01).
Data as JSON: /api/errors/f35659799432fc97.
Report an issue: GitHub.