redis/go-redis · error
unexpected search result format
Error message
unexpected search result format
What it means
parseFTSearch received an empty array for an FT.SEARCH reply (RESP2 path). A well-formed reply always has at least one element — the total-results integer — so zero elements means the response shape is not what this library expects.
Source
Thrown at search_commands.go:2608
val = make([]SpellCheckResult, len(cmd.val))
for i, result := range cmd.val {
val[i] = SpellCheckResult{
Term: result.Term,
}
if result.Suggestions != nil {
val[i].Suggestions = slices.Clone(result.Suggestions)
}
}
}
return &FTSpellCheckCmd{
baseCmd: cmd.cloneBaseCmd(),
val: val,
}
}
func parseFTSearch(data []interface{}, noContent, withScores, withPayloads, withSortKeys bool) (FTSearchResult, error) {
if len(data) < 1 {
return FTSearchResult{}, fmt.Errorf("unexpected search result format")
}
total, ok := data[0].(int64)
if !ok {
return FTSearchResult{}, fmt.Errorf("invalid total results format")
}
var results []Document
for i := 1; i < len(data); {
docID, ok := data[i].(string)
if !ok {
return FTSearchResult{}, fmt.Errorf("invalid document ID format")
}
doc := Document{
ID: docID,
Fields: make(map[string]string),
}View on GitHub (pinned to c5cad058c7)
Solutions
- Inspect the raw reply to confirm the server really sent an empty array
- Remove/fix proxies or hooks that rewrite command replies
- Confirm the target is RediSearch (FT.INFO) and versions are compatible
- Check AddHook implementations aren't replacing cmd replies with empty slices
Example fix
// before: assuming reply is fine
res, _ := rdb.FTSearch(ctx, "idx", "query").Result()
// after: log raw reply on parse failure
res, err := rdb.FTSearch(ctx, "idx", "query").Result()
if err != nil {
log.Printf("ftsearch: %v", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the search index exists before querying
if err := rdb.FTInfo(ctx, index).Err(); err != nil {
return fmt.Errorf("index missing: %w", err)
} Type guard
func looksLikeFTSearchReply(v interface{}) bool {
slice, ok := v.([]interface{})
return ok && len(slice) >= 1
} Try / catch
res, err := rdb.FTSearch(ctx, "idx", q).Result()
if err != nil {
if strings.Contains(err.Error(), "unexpected search result format") {
log.Printf("malformed FT.SEARCH reply (proxy/server issue): %v", err)
return emptyResult, nil
}
return err
} Prevention
- Don't route FT.SEARCH through reply-rewriting proxies
- Audit AddHook implementations for reply mutation
- Confirm Protocol option suits your server/proxy combination
When it happens
Trigger: FTSearch with RESP2 (Protocol: 2) when the server/proxy returns an empty array instead of [total, id, fields, ...]; a fault-injecting proxy truncating replies; custom middleware returning an empty []interface{}.
Common situations: Proxy/middleware mangling FT.SEARCH responses; pointing at a non-RediSearch server; tests with truncated mock replies.
Related errors
- invalid total results format
- invalid document ID format
- invalid score format
- invalid document fields format
- invalid field value format
AI-assisted analysis of redis/go-redis@c5cad058c7 (2026-09-01).
Data as JSON: /api/errors/f433ff4b3d3ef0c4.
Report an issue: GitHub.