{"record":{"id":"4d0e1c5deec4ccd5","repo":"redis/go-redis","slug":"invalid-cursor-result-format","errorCode":null,"errorMessage":"invalid cursor result format","messagePattern":"invalid cursor result format","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"search_commands.go","lineNumber":3055,"sourceCode":"func parseFTHybrid(data []interface{}, withCursor bool) (FTHybridResult, *FTHybridCursorResult, error) {\n\t// Convert to map\n\tresultMap := make(map[string]interface{})\n\tfor i := 0; i < len(data); i += 2 {\n\t\tif i+1 < len(data) {\n\t\t\tkey, ok := data[i].(string)\n\t\t\tif !ok {\n\t\t\t\treturn FTHybridResult{}, nil, fmt.Errorf(\"invalid key type at index %d\", i)\n\t\t\t}\n\t\t\tresultMap[key] = data[i+1]\n\t\t}\n\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","sourceCodeStart":3037,"sourceCodeEnd":3073,"githubUrl":"https://github.com/redis/go-redis/blob/c5cad058c72f58370553b48566302303cf8a2e89/search_commands.go#L3037-L3073","documentation":"When FT.HYBRID is run WITHCURSOR, the reply map must contain integer cursor IDs under the keys \"SEARCH\" and \"VSIM\". If either key is missing or its value is not an int64, the client cannot construct the FTHybridCursorResult and returns this error. It means the cursor reply from the server did not match the expected two-cursor structure.","triggerScenarios":"Calling FTHybrid with the Cursor option against a server that does not return the expected {\"SEARCH\": int64, \"VSIM\": int64} cursor map — e.g. a RediSearch version with different cursor reply keys, or a proxy rewriting the reply.","commonSituations":"Server upgrade/downgrade changing FT.HYBRID cursor reply layout; hitting a non-Redis-compatible endpoint that lacks hybrid cursor support; RESP2/RESP3 protocol mismatch altering value types (e.g. cursor returned as string).","solutions":["Upgrade go-redis (and/or the Redis stack server) so client and server agree on the FT.HYBRID cursor reply format","Ensure Protocol: 3 is negotiated; cursor reply parsing may differ between RESP2 and RESP3","Capture the raw reply via a hook/MONITOR and confirm the \"SEARCH\"/\"VSIM\" keys and their types","Avoid proxies that rewrite reply values (e.g. converting int64 cursors to strings)"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// only request cursor when the server build supports hybrid cursors\nif !serverSupportsHybridCursor { opts.Cursor = false }","typeGuard":"func hasHybridCursorReply(m map[interface{}]interface{}) bool {\n    _, ok1 := m[\"SEARCH\"].(int64)\n    _, ok2 := m[\"VSIM\"].(int64)\n    return ok1 && ok2\n}","tryCatchPattern":"res, cursor, err := hybridCmd.Result()\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid cursor result format\") {\n        // fall back to non-cursor query without CURSOR option\n        return runHybridWithoutCursor(ctx)\n    }\n    return err\n}","preventionTips":["Verify server version supports FT.HYBRID WITHCURSOR with SEARCH/VSIM cursor keys","Do not route search traffic through value-rewriting proxies","Add an integration test covering the cursor path"],"tags":["redis","search","cursor","resp-protocol"],"backgroundTag":"unexpected-response-shape","analyzedSha":"c5cad058c72f58370553b48566302303cf8a2e89","analyzedAt":"2026-09-01T06:50:53.388Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}