{"record":{"id":"f126b6562307ed21","repo":"redis/go-redis","slug":"invalid-item-key-format","errorCode":null,"errorMessage":"invalid item key format","messagePattern":"invalid item key format","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"search_commands.go","lineNumber":3106,"sourceCode":"\t\t\t\t\titemMap[keyStr] = v\n\t\t\t\t}\n\t\t\t}\n\t\t\tresults = append(results, itemMap)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Fall back to array format (RESP2 format - key-value pairs)\n\t\titemData, ok := item.([]interface{})\n\t\tif !ok {\n\t\t\treturn FTHybridResult{}, nil, fmt.Errorf(\"invalid result item format\")\n\t\t}\n\n\t\titemMap := make(map[string]interface{})\n\t\tfor i := 0; i < len(itemData); i += 2 {\n\t\t\tif i+1 < len(itemData) {\n\t\t\t\tkey, ok := itemData[i].(string)\n\t\t\t\tif !ok {\n\t\t\t\t\treturn FTHybridResult{}, nil, fmt.Errorf(\"invalid item key format\")\n\t\t\t\t}\n\t\t\t\titemMap[key] = itemData[i+1]\n\t\t\t}\n\t\t}\n\t\tresults = append(results, itemMap)\n\t}\n\n\t// Optional warnings; accept both \"warning\" (as FT.SEARCH/FT.AGGREGATE) and \"warnings\".\n\tvar warnings []string\n\twarningsData, ok := resultMap[\"warning\"].([]interface{})\n\tif !ok {\n\t\twarningsData, ok = resultMap[\"warnings\"].([]interface{})\n\t}\n\tif ok {\n\t\twarnings = make([]string, 0, len(warningsData))\n\t\tfor _, w := range warningsData {\n\t\t\tif ws, ok := w.(string); ok {\n\t\t\t\twarnings = append(warnings, ws)","sourceCodeStart":3088,"sourceCodeEnd":3124,"githubUrl":"https://github.com/redis/go-redis/blob/c5cad058c72f58370553b48566302303cf8a2e89/search_commands.go#L3088-L3124","documentation":"In the RESP2 fallback path for FT.HYBRID result rows, keys at even indices must be strings. If a row's key is not a string, field extraction fails and this error is returned with the row context. It indicates a malformed key/value pair in a result item.","triggerScenarios":"Calling FTHybrid when a RESP2-format result row contains a non-string key at an even index — e.g. binary keys, or a proxy converting keys to other types.","commonSituations":"Proxies or middlewares re-encoding keys; server builds emitting different row layouts; incorrect test fixtures.","solutions":["Dump the raw reply to inspect the offending key type","Remove middlewares that re-encode reply keys","Align go-redis and server versions","Fix fixtures so row keys are strings"],"exampleFix":"// before\n[]interface{}{int64(1), \"value\"}\n// after\n[]interface{}{\"id\", \"doc1\"}","handlingStrategy":"type-guard","validationCode":"// pre-flight a simple hybrid query to validate reply shape\n_, _, err := rdb.FTHybrid(ctx, \"idx\", \"*\", opts).Result()","typeGuard":"func rowKeysAreStrings(row []interface{}) bool {\n    for i := 0; i+1 < len(row); i += 2 {\n        if _, ok := row[i].(string); !ok { return false }\n    }\n    return true\n}","tryCatchPattern":"res, _, err := hybridCmd.Result()\nif err != nil && strings.Contains(err.Error(), \"invalid item key format\") {\n    // inspect raw reply; likely a proxy or server build issue\n    return ErrMalformedReply\n}","preventionTips":["Use string-typed field names end-to-end; strip binary keys upstream","Keep server and client versions aligned","Validate fixtures: row keys must be strings at even indices"],"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"}