redis/go-redis · error
redis: FT.AGGREGATE COLLECT requires FieldsAll or a non-empt
Error message
redis: FT.AGGREGATE COLLECT requires FieldsAll or a non-empty Fields list
What it means
buildCollectArgs requires exactly one of two field-selection modes for the COLLECT step: either FieldsAll (emitting FIELDS *) or a non-empty Fields list. If neither is set there is nothing to collect, so argument construction fails with this error.
Source
Thrown at search_collect.go:99
// The serializer computes <narg> as len(args), which matches the COLLECT
// contract: narg counts every FIELDS/DISTINCT/SORTBY/LIMIT token.
func buildCollectArgs(o FTAggregateCollect) ([]interface{}, error) {
args := make([]interface{}, 0, 8)
// FIELDS (required): either * or a counted list of @-names.
switch {
case o.FieldsAll:
args = append(args, "FIELDS", "*")
case len(o.Fields) > 0:
args = append(args, "FIELDS", len(o.Fields))
for _, f := range o.Fields {
if strings.TrimLeft(f, "@") == "" {
return nil, fmt.Errorf("redis: FT.AGGREGATE COLLECT: empty field name in Fields")
}
args = append(args, ensureAtPrefix(f))
}
default:
return nil, fmt.Errorf("redis: FT.AGGREGATE COLLECT requires FieldsAll or a non-empty Fields list")
}
// DISTINCT (optional, forward-compatible).
if o.Distinct {
args = append(args, "DISTINCT")
}
// SORTBY (optional). sort_narg counts each field plus its optional
// direction token.
if len(o.SortBy) > 0 {
sortTokens := make([]interface{}, 0, len(o.SortBy)*2)
for _, s := range o.SortBy {
if strings.TrimLeft(s.FieldName, "@") == "" {
return nil, fmt.Errorf("redis: FT.AGGREGATE COLLECT: empty field name in SortBy")
}
if s.Asc && s.Desc {
return nil, fmt.Errorf("redis: FT.AGGREGATE COLLECT: ASC and DESC are mutually exclusive")
}View on GitHub (pinned to c5cad058c7)
Solutions
- Set FieldsAll: true to collect all fields
- Populate Fields with at least one valid field name
- Guard the construction site so an empty field list falls back to FieldsAll
Example fix
// before
r := redis.NewCollectReducer(redis.CollectOptions{})
// after
r := redis.NewCollectReducer(redis.CollectOptions{FieldsAll: true}) Defensive patterns
Strategy: validation
Validate before calling
if !opts.FieldsAll && len(opts.Fields) == 0 {
return fmt.Errorf("CollectOptions requires FieldsAll or a non-empty Fields list")
} Prevention
- Default to FieldsAll:true when building options from config
- Check len(Fields) before constructing CollectOptions
- Centralize CollectOptions construction in one enforcing helper
When it happens
Trigger: NewCollectReducer with CollectOptions where FieldsAll is false and Fields is empty or nil; buildCollectArgs falls to the default branch and returns this error.
Common situations: Constructing CollectOptions with a dynamically built Fields slice that ended up empty; forgetting to set FieldsAll when no explicit fields are wanted.
Understand the failure class
Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.
Related errors
- redis: FT.AGGREGATE COLLECT: empty field name in Fields
- redis: FT.AGGREGATE COLLECT: empty field name in SortBy
- redis: FT.AGGREGATE COLLECT: ASC and DESC are mutually exclu
- FT.AGGREGATE: SortByMax must follow a SortBy step
- redis: COLLECT value has type %T, want array of entries
AI-assisted analysis of redis/go-redis@c5cad058c7 (2026-09-01).
Data as JSON: /api/errors/46b488191fe311a9.
Report an issue: GitHub.