redis/go-redis · error
redis: FT.AGGREGATE COLLECT: ASC and DESC are mutually exclu
Error message
redis: FT.AGGREGATE COLLECT: ASC and DESC are mutually exclusive
What it means
Within a single COLLECT SORTBY field, ASC and DESC are mutually exclusive — a field sorts in one direction only. buildCollectArgs rejects entries with both Asc and Desc set to true rather than emitting an ambiguous SORTBY clause.
Source
Thrown at search_collect.go:116
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")
}
sortTokens = append(sortTokens, ensureAtPrefix(s.FieldName))
switch {
case s.Desc:
sortTokens = append(sortTokens, "DESC")
case s.Asc:
sortTokens = append(sortTokens, "ASC")
// neither set: ASC is the server default; emit nothing.
}
}
args = append(args, "SORTBY", len(sortTokens))
args = append(args, sortTokens...)
}
// LIMIT (optional).
if o.Limit != nil {
args = append(args, "LIMIT", o.Limit.Offset, o.Limit.Count)
}View on GitHub (pinned to c5cad058c7)
Solutions
- Set exactly one of Asc or Desc (or neither, for the server default)
- Use a single direction enum/helper instead of two booleans
- Clear the opposite flag whenever one is set
Example fix
// before
f := redis.CollectSortByField{FieldName: "@price", Asc: true, Desc: true}
// after
f := redis.CollectSortByField{FieldName: "@price", Desc: true} Defensive patterns
Strategy: validation
Validate before calling
if s.Asc && s.Desc {
return fmt.Errorf("ASC and DESC are mutually exclusive for field %s", s.FieldName)
} Prevention
- Model direction as an enum (Asc/Desc/None) rather than two booleans
- Normalize direction flags in a SortBy-field constructor
- Unit-test that Asc and Desc are never both set
When it happens
Trigger: A CollectOptions.SortBy entry with both Asc: true and Desc: true; buildCollectArgs returns this error during argument construction.
Common situations: Merging two config sources that each set a direction flag; copying a struct and forgetting to clear the old direction; a UI toggle that sets both booleans.
Related errors
- 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
- 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/4527fc81f0e04b61.
Report an issue: GitHub.