{"record":{"id":"3ce84ba400945631","repo":"redis/go-redis","slug":"invalid-document-fields-format","errorCode":null,"errorMessage":"invalid document fields format","messagePattern":"invalid document fields format","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"search_commands.go","lineNumber":2667,"sourceCode":"\t\t\t}\n\t\t}\n\n\t\tif withSortKeys && i < len(data) {\n\t\t\tif sortKey, ok := data[i].(string); ok {\n\t\t\t\tdoc.SortKey = &sortKey\n\t\t\t\ti++\n\t\t\t}\n\t\t}\n\n\t\tif i < len(data) {\n\t\t\tfields, ok := data[i].([]interface{})\n\t\t\tif !ok {\n\t\t\t\tif data[i] == proto.Nil || data[i] == nil {\n\t\t\t\t\tdoc.Error = proto.Nil\n\t\t\t\t\tdoc.Fields = map[string]string{}\n\t\t\t\t\tfields = []interface{}{}\n\t\t\t\t} else {\n\t\t\t\t\treturn FTSearchResult{}, fmt.Errorf(\"invalid document fields format\")\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor j := 0; j < len(fields); j += 2 {\n\t\t\t\tkey, ok := fields[j].(string)\n\t\t\t\tif !ok {\n\t\t\t\t\treturn FTSearchResult{}, fmt.Errorf(\"invalid field key format\")\n\t\t\t\t}\n\t\t\t\tvalue, ok := fields[j+1].(string)\n\t\t\t\tif !ok {\n\t\t\t\t\treturn FTSearchResult{}, fmt.Errorf(\"invalid field value format\")\n\t\t\t\t}\n\t\t\t\tdoc.Fields[key] = value\n\t\t\t}\n\t\t\ti++\n\t\t}\n\n\t\tresults = append(results, doc)","sourceCodeStart":2649,"sourceCodeEnd":2685,"githubUrl":"https://github.com/redis/go-redis/blob/c5cad058c72f58370553b48566302303cf8a2e89/search_commands.go#L2649-L2685","documentation":"The final element of each FT.SEARCH (RESP2) document entry must be the fields array (a []interface{} of key/value pairs), or nil when the document was deleted mid-index (which go-redis maps to doc.Error). Any other type at that position makes the parser fail with this error.","triggerScenarios":"FTSearch reply where the fields element is a string/map/int instead of an array or nil — typically a reply shape shifted by missing WithScores/WithPayloads elements, a proxy rewriting the reply, or a malformed mock.","commonSituations":"Options mismatch (NoContent false but server sent no fields array); custom middleware; non-RediSearch server; hand-crafted test data using a map for fields.","solutions":["Check the raw reply's element layout and confirm each doc ends with an array or nil","Make FTSearchOptions flags match the FT.SEARCH arguments actually issued","Fix proxies/hooks/mocks that reshape the reply","Upgrade to matched go-redis/RediSearch versions"],"exampleFix":"// before: mock uses a map for fields\nmock := []interface{}{int64(1), \"doc:1\", map[string]string{\"t\": \"v\"}}\n\n// after: fields must be a flat array\ncmd := rdb.FTSearch(ctx, \"idx\", \"q\")\nmock := []interface{}{int64(1), \"doc:1\", []interface{}{\"t\", \"v\"}}","handlingStrategy":"type-guard","validationCode":"// Ensure the trailing element of each doc entry is an array or nil\nlast := mockDocEntry[len(mockDocEntry)-1]\nswitch last.(type) {\ncase []interface{}, nil:\ndefault:\n\tpanic(\"fields element must be []interface{} or nil\")\n}","typeGuard":"func isFieldsElement(v interface{}) bool {\n\tif v == nil {\n\t\treturn true // deleted doc case\n\t}\n\t_, ok := v.([]interface{})\n\treturn ok\n}","tryCatchPattern":"res, err := rdb.FTSearch(ctx, \"idx\", q).Result()\nif err != nil {\n\tif strings.Contains(err.Error(), \"invalid document fields\") {\n\t\tlog.Printf(\"unexpected fields element in FT.SEARCH reply: %v\", err)\n\t\treturn emptyDocs, nil\n\t}\n\treturn err\n}","preventionTips":["Model mocks on the real wire format: flat key/value arrays, not maps","Remember go-redis treats a nil fields element as a deleted document (doc.Error)","Keep NoContent/WithScores flags consistent with the issued command"],"tags":["go-redis","ftsearch","resp-parsing","documents"],"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"}