{"record":{"id":"fe3765d86113f167","repo":"redis/go-redis","slug":"invalid-total-results-format-fe3765","errorCode":null,"errorMessage":"invalid total_results format","messagePattern":"invalid total_results format","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"search_commands.go","lineNumber":3066,"sourceCode":"\t}\n\n\t// Handle cursor result\n\tif withCursor {\n\t\tsearchCursorID, ok1 := resultMap[\"SEARCH\"].(int64)\n\t\tvsimCursorID, ok2 := resultMap[\"VSIM\"].(int64)\n\t\tif !ok1 || !ok2 {\n\t\t\treturn FTHybridResult{}, nil, fmt.Errorf(\"invalid cursor result format\")\n\t\t}\n\t\treturn FTHybridResult{}, &FTHybridCursorResult{\n\t\t\tSearchCursorID: int(searchCursorID),\n\t\t\tVsimCursorID:   int(vsimCursorID),\n\t\t}, nil\n\t}\n\n\t// Parse regular result\n\ttotalResults, ok := resultMap[\"total_results\"].(int64)\n\tif !ok {\n\t\treturn FTHybridResult{}, nil, fmt.Errorf(\"invalid total_results format\")\n\t}\n\n\tresultsData, ok := resultMap[\"results\"].([]interface{})\n\tif !ok {\n\t\treturn FTHybridResult{}, nil, fmt.Errorf(\"invalid results format\")\n\t}\n\n\t// Parse each result item\n\tresults := make([]map[string]interface{}, 0, len(resultsData))\n\tfor _, item := range resultsData {\n\t\t// Try parsing as map[string]interface{} first (RESP3 format)\n\t\tif itemMap, ok := item.(map[string]interface{}); ok {\n\t\t\tresults = append(results, itemMap)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Try parsing as map[interface{}]interface{} (alternative RESP3 format)\n\t\tif rawMap, ok := item.(map[interface{}]interface{}); ok {","sourceCodeStart":3048,"sourceCodeEnd":3084,"githubUrl":"https://github.com/redis/go-redis/blob/c5cad058c72f58370553b48566302303cf8a2e89/search_commands.go#L3048-L3084","documentation":"The FT.HYBRID reply parser expects a numeric field \"total_results\" in the reply map. If that key is missing or its value is not an int64, the client returns this error. It signals the server reply does not follow the expected FT.HYBRID result structure.","triggerScenarios":"Calling FTHybrid against a server whose reply omits \"total_results\" or returns it with a different type/name (different RediSearch build, proxy rewrite, or RESP protocol mismatch).","commonSituations":"Version skew between go-redis and the Redis stack server; a compatibility layer or RESP proxy renaming/re-typing fields; tests with hand-built maps lacking the key.","solutions":["Align go-redis and server versions so the FT.HYBRID reply contract matches","Use Protocol: 3 to get the RESP3 map reply path the parser expects","Inspect the raw reply (ProcessHook or MONITOR) to confirm whether \"total_results\" exists and its type","Fix mocks to include \"total_results\" as int64"],"exampleFix":"// before\nmap[interface{}]interface{}{\"results\": []interface{}{}}\n// after\nmap[interface{}]interface{}{\"total_results\": int64(0), \"results\": []interface{}{}}","handlingStrategy":"validation","validationCode":"// pre-flight: ensure the endpoint responds to a basic FT.HYBRID call before relying on it\n_, err := rdb.Do(ctx, \"FT.HYBRID\", \"idx\", \"QUERY\", \"*\", \"VSIM\", \"vec\", \"->\", \"1\").Result()","typeGuard":"func hasTotalResults(m map[interface{}]interface{}) bool {\n    _, ok := m[\"total_results\"].(int64)\n    return ok\n}","tryCatchPattern":"res, _, err := hybridCmd.Result()\nif err != nil && strings.Contains(err.Error(), \"invalid total_results format\") {\n    // capture raw reply with a ProcessHook for bug report; treat as server incompatibility\n    return ErrReplyShapeUnsupported\n}","preventionTips":["Keep go-redis and Redis Stack versions in the tested compatibility matrix","Add integration tests for FT.HYBRID result parsing","Avoid middleware that renames or re-types reply fields"],"tags":["redis","search","resp-protocol","deserialization"],"backgroundTag":"unexpected-response-shape","analyzedSha":"c5cad058c72f58370553b48566302303cf8a2e89","analyzedAt":"2026-09-01T06:50:53.388Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}