redis/go-redis · error
invalid results format
Error message
invalid results format
What it means
The FT.HYBRID parser expects the reply map's "results" field to be an []interface{} list of per-document items. If it is missing or of another type, this error is returned. It indicates the server reply structure does not match the expected hybrid search result format.
Solutions
- Align go-redis and Redis stack versions
- Force Protocol: 3 so the expected RESP3 reply shape is used
- Dump the raw reply with a hook to verify the "results" field type
- Correct test fixtures to use []interface{} for "results"
Example fix
// before
map[interface{}]interface{}{"total_results": int64(1), "results": "none"}
// after
map[interface{}]interface{}{"total_results": int64(1), "results": []interface{}{}} Defensive patterns
Strategy: validation
Validate before calling
// smoke-test the hybrid path at startup err := rdb.Do(ctx, "FT.HYBRID", "idx", "QUERY", "*", "VSIM", "vec", "->", "1").Err()
Type guard
func hasResultsArray(m map[interface{}]interface{}) bool {
_, ok := m["results"].([]interface{})
return ok
} Try / catch
res, _, err := hybridCmd.Result()
if err != nil && strings.Contains(err.Error(), "invalid results format") {
// log raw reply, disable hybrid search feature flag
featureFlags.Set("hybrid_search", false)
return err
} Prevention
- Test the full FT.HYBRID reply path in CI against the target server version
- Use Protocol: 3 for hybrid search
- Gate the hybrid feature behind a runtime capability check
When it happens
Trigger: Calling FTHybrid when the reply's "results" value is absent or not an array — e.g. server emitting a different container type, a proxy rewriting the reply, or RESP2/RESP3 shape mismatch.
Common situations: Version skew between client and RediSearch; middleware transforming arrays into other types; incorrect test fixtures.
Related errors
- invalid item key format
- invalid key type at index
- invalid result item format
- invalid total_results format
- invalid cursor result format
AI-assisted analysis of redis/go-redis@c5cad058c7 (2026-09-01).
Data as JSON: /api/errors/d5200ac4a72e4df2.
Report an issue: GitHub.
Appendix: source
Thrown at search_commands.go:3071
vsimCursorID, ok2 := resultMap["VSIM"].(int64)
if !ok1 || !ok2 {
return FTHybridResult{}, nil, fmt.Errorf("invalid cursor result format")
}
return FTHybridResult{}, &FTHybridCursorResult{
SearchCursorID: int(searchCursorID),
VsimCursorID: int(vsimCursorID),
}, nil
}
// Parse regular result
totalResults, ok := resultMap["total_results"].(int64)
if !ok {
return FTHybridResult{}, nil, fmt.Errorf("invalid total_results format")
}
resultsData, ok := resultMap["results"].([]interface{})
if !ok {
return FTHybridResult{}, nil, fmt.Errorf("invalid results format")
}
// Parse each result item
results := make([]map[string]interface{}, 0, len(resultsData))
for _, item := range resultsData {
// Try parsing as map[string]interface{} first (RESP3 format)
if itemMap, ok := item.(map[string]interface{}); ok {
results = append(results, itemMap)
continue
}
// Try parsing as map[interface{}]interface{} (alternative RESP3 format)
if rawMap, ok := item.(map[interface{}]interface{}); ok {
itemMap := make(map[string]interface{})
for k, v := range rawMap {
if keyStr, ok := k.(string); ok {
itemMap[keyStr] = v
}View on GitHub (pinned to c5cad058c7)