go-redis/redis · error
FT.SEARCH: ASC and DESC are mutually exclusive
Error message
FT.SEARCH: ASC and DESC are mutually exclusive
What it means
Returned by the FTSearchQuery query builder (search_commands.go:3376-3378): for any entry in options.SortBy, you cannot set both Asc:true and Desc:true on the same SortBy element. The library refuses to emit a contradictory SORTBY clause.
Source
Thrown at search_commands.go:3377
}
if options.Expander != "" {
queryArgs = append(queryArgs, "EXPANDER", options.Expander)
}
if options.Scorer != "" {
queryArgs = append(queryArgs, "SCORER", options.Scorer)
}
if options.ExplainScore {
queryArgs = append(queryArgs, "EXPLAINSCORE")
}
if options.Payload != "" {
queryArgs = append(queryArgs, "PAYLOAD", options.Payload)
}
if options.SortBy != nil {
queryArgs = append(queryArgs, "SORTBY")
for _, sortBy := range options.SortBy {
queryArgs = append(queryArgs, sortBy.FieldName)
if sortBy.Asc && sortBy.Desc {
return nil, fmt.Errorf("FT.SEARCH: ASC and DESC are mutually exclusive")
}
if sortBy.Asc {
queryArgs = append(queryArgs, "ASC")
}
if sortBy.Desc {
queryArgs = append(queryArgs, "DESC")
}
}
if options.SortByWithCount {
queryArgs = append(queryArgs, "WITHCOUNT")
}
}
if options.LimitOffset >= 0 && options.Limit > 0 {
queryArgs = append(queryArgs, "LIMIT", options.LimitOffset, options.Limit)
}
if options.Params != nil {
queryArgs = append(queryArgs, "PARAMS", len(options.Params)*2)
for key, value := range options.Params {View on GitHub (pinned to 36d97525cd)
Solutions
- Set exactly one of Asc or Desc per SortBy entry.
- Leave both false for the server default direction.
- Validate options.SortBy before calling FTSearchQuery.
Example fix
// before
q, err := redis.FTSearchQuery("*", &redis.FTSearchOptions{
SortBy: []redis.FTSearchSortBy{{FieldName: "ts", Asc: true, Desc: true}},
})
// after
q, err := redis.FTSearchQuery("*", &redis.FTSearchOptions{
SortBy: []redis.FTSearchSortBy{{FieldName: "ts", Asc: true}},
}) Defensive patterns
Strategy: validation
Validate before calling
// Reject contradictory SortBy entries before building the query.
for _, s := range opts.SortBy {
if s.Asc && s.Desc {
return fmt.Errorf("SortBy %q: pick ASC or DESC, not both", s.FieldName)
}
} Try / catch
q, err := redis.FTSearchQuery(qs, opts)
if err != nil && strings.Contains(err.Error(), "ASC and DESC are mutually exclusive") {
// fix the SortBy entry that has both flags set
} Prevention
- Set at most one of Asc/Desc per FTSearchSortBy entry.
- Centralize SortBy construction in a helper that enforces the rule.
- Validate options before calling FTSearchQuery.
When it happens
Trigger: Constructing a SearchQuery via FTSearchQuery with a redis.FTSearchSortBy{Asc: true, Desc: true, ...} entry.
Common situations: Copy-paste from another call where the opposite flag was set, or programmatic construction that defaulted both booleans true.
Related errors
- unexpected search result format
- invalid total results format
- invalid document ID format
- invalid score format
- invalid document fields format
AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06).
Data as JSON: /data/errors/133677286359ffcb.json.
Report an issue: GitHub.