{"record":{"id":"ec8b40f381114f1c","repo":"redis/go-redis","slug":"invalid-total-results-format","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":2613,"sourceCode":"\t\t\tif result.Suggestions != nil {\n\t\t\t\tval[i].Suggestions = slices.Clone(result.Suggestions)\n\t\t\t}\n\t\t}\n\t}\n\treturn &FTSpellCheckCmd{\n\t\tbaseCmd: cmd.cloneBaseCmd(),\n\t\tval:     val,\n\t}\n}\n\nfunc parseFTSearch(data []interface{}, noContent, withScores, withPayloads, withSortKeys bool) (FTSearchResult, error) {\n\tif len(data) < 1 {\n\t\treturn FTSearchResult{}, fmt.Errorf(\"unexpected search result format\")\n\t}\n\n\ttotal, ok := data[0].(int64)\n\tif !ok {\n\t\treturn FTSearchResult{}, fmt.Errorf(\"invalid total results format\")\n\t}\n\n\tvar results []Document\n\tfor i := 1; i < len(data); {\n\t\tdocID, ok := data[i].(string)\n\t\tif !ok {\n\t\t\treturn FTSearchResult{}, fmt.Errorf(\"invalid document ID format\")\n\t\t}\n\n\t\tdoc := Document{\n\t\t\tID:     docID,\n\t\t\tFields: make(map[string]string),\n\t\t}\n\t\ti++\n\n\t\tif noContent {\n\t\t\tresults = append(results, doc)\n\t\t\tcontinue","sourceCodeStart":2595,"sourceCodeEnd":2631,"githubUrl":"https://github.com/redis/go-redis/blob/c5cad058c72f58370553b48566302303cf8a2e89/search_commands.go#L2595-L2631","documentation":"The first element of the FT.SEARCH (RESP2) reply must be the total number of results as a RESP integer (Go int64). If data[0] is not an int64, the reply does not follow the RediSearch wire format and this error is returned.","triggerScenarios":"FTSearch reply where the total is a string, a map, or nil — typically because a proxy translated the reply, a non-RediSearch server answered, or a RESP2/RESP3 mismatch altered decoding.","commonSituations":"Client Protocol setting incompatible with the proxy; custom mock replies using int instead of int64 (Go type assertion fails: int != int64); older module versions.","solutions":["Verify server is RediSearch and the client Protocol option matches (3 for RESP3-aware setups)","If using mocks, encode the total as int64, not int: []interface{}{int64(2), ...}","Bypass or fix any reply-rewriting proxy/hook","Capture the raw reply to see what data[0] actually is"],"exampleFix":"// before: mock uses int\nmock := []interface{}{2, \"doc:1\", []interface{}{\"title\", \"hi\"}}\n\n// after: mock uses int64 (RESP integers decode to int64)\nmock := []interface{}{int64(2), \"doc:1\", []interface{}{\"title\", \"hi\"}}","handlingStrategy":"type-guard","validationCode":"// Confirm RESP integers decode as int64 in your mocks\ntotal, ok := mockReply[0].(int64)\nif !ok {\n\tpanic(\"mock total must be int64, not int\")\n}","typeGuard":"func isInt64(v interface{}) bool {\n\t_, ok := v.(int64)\n\treturn ok\n}","tryCatchPattern":"res, err := rdb.FTSearch(ctx, \"idx\", q).Result()\nif err != nil {\n\tif strings.Contains(err.Error(), \"invalid total results\") {\n\t\tlog.Printf(\"FT.SEARCH reply shape unexpected: %v\", err)\n\t\treturn fallbackResult\n\t}\n\treturn err\n}","preventionTips":["In mocks, always use int64 for RESP integers","Keep RESP2/RESP3 protocol setting consistent across client, server, proxy","Test parsing against real server replies, not only synthetic ones"],"tags":["go-redis","ftsearch","resp-parsing","int64"],"backgroundTag":"resp-reply-parse-failed","analyzedSha":"c5cad058c72f58370553b48566302303cf8a2e89","analyzedAt":"2026-09-01T06:50:53.388Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}