{"id":"78dc7dd367c5fee3","repo":"go-redis/redis","slug":"unexpected-type-t-want-map-or-key-value-array","errorCode":null,"errorMessage":"unexpected type %T, want map or key/value array","messagePattern":"unexpected type %T, want map or key/value array","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"search_collect.go","lineNumber":233,"sourceCode":"\t\t}\n\t\treturn out, nil\n\tcase map[string]interface{}: // already string-keyed\n\t\treturn m, nil\n\tcase []interface{}: // RESP2 flat [field, value, field, value, ...]\n\t\tif len(m)%2 != 0 {\n\t\t\treturn nil, fmt.Errorf(\"odd-length key/value array of length %d\", len(m))\n\t\t}\n\t\tout := make(CollectEntry, len(m)/2)\n\t\tfor i := 0; i < len(m); i += 2 {\n\t\t\tkey, ok := m[i].(string)\n\t\t\tif !ok {\n\t\t\t\tkey = fmt.Sprint(m[i])\n\t\t\t}\n\t\t\tout[key] = m[i+1]\n\t\t}\n\t\treturn out, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unexpected type %T, want map or key/value array\", e)\n\t}\n}\n","sourceCodeStart":215,"sourceCodeEnd":236,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/search_collect.go#L215-L236","documentation":"Returned by parseCollectEntry when an individual COLLECT entry is neither a map (RESP3 map[interface{}]interface{} or map[string]interface{}) nor a flat key/value array ([]interface{}). The '%T' shows the actual Go type, e.g. string or int64, that appeared where an entry map was expected.","triggerScenarios":"AggregateRow.Collect over an array whose element is a scalar (string, number, bulk-string error) rather than a per-entry map/array. Triggered purely during response decoding.","commonSituations":"Server returned an error string inline in the results array instead of as a top-level error. Protocol mismatch (RESP3 expected, RESP2 returned, or vice versa) causing the decoder to see a bare scalar. A non-COLLECT reducer's output landing in the same alias. Proxy rewriting the reply.","solutions":["Inspect the raw reply (cmd.RawVal()) to identify the scalar and where it came from.","Confirm the alias is exclusively used by a COLLECT reducer and not shared with another reducer/field.","Verify the negotiated protocol (RESP2 vs RESP3) matches the server's reply type.","Check server/proxy version and logs for an upstream error that was serialized into the results array."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isCollectEntryShape(e interface{}) bool {\n\tswitch e.(type) {\n\tcase map[interface{}]interface{}, map[string]interface{}, []interface{}:\n\t\treturn true\n\t}\n\treturn false\n}","tryCatchPattern":"col, err := row.Collect(alias)\nif err != nil {\n    raw, _ := cmd.RawResult()\n    log.Printf(\"COLLECT entry malformed on %q; raw=%v err=%v\", alias, raw, err)\n    return nil, err\n}","preventionTips":["Ensure the alias is used solely by a COLLECT reducer.","Verify protocol negotiation (RESP2 vs RESP3) matches the server reply.","Inspect cmd.RawVal() when this fires to identify the scalar that landed where an entry map was expected."],"tags":["ft-aggregate","collect","response-decoding","type-mismatch"],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}