go-redis/redis · error

unexpected response type: %T

Error message

unexpected response type: %T

What it means

Returned by AggregateCmd.readReply in the non-RESP3 branch when the raw reply is not a []interface{}. FT.AGGREGATE RESP2 replies must be arrays; a bulk string, integer, nil, or map landing in this branch means the reply does not match either expected FT.AGGREGATE shape.

Source

Thrown at search_commands.go:1022

		if mapVal, ok := cmd.rawVal.(map[interface{}]interface{}); ok {
			cmd.val, err = parseFTAggregateMapRESP3(mapVal)
		} else {
			return fmt.Errorf("unexpected RESP3 response type: %T", cmd.rawVal)
		}
		return err
	}

	// RESP2 format or error response - use ReadReply to handle errors properly
	data, err := rd.ReadReply()
	if err != nil {
		return err
	}
	cmd.rawVal = data // Store raw value for debugging
	if dataSlice, ok := data.([]interface{}); ok {
		cmd.val, err = ProcessAggregateResult(dataSlice)
		return err
	}
	return fmt.Errorf("unexpected response type: %T", data)
}

// parseFTAggregateMapRESP3 parses the RESP3 format response from FT.AGGREGATE.
// It takes a map[interface{}]interface{} which is the raw response from ReadReply().
// RESP3 format:
//
//	%5
//	  $10 attributes => *0
//	  $13 total_results => :N
//	  $6 format => $6 STRING
//	  $7 results => *N (array of maps with extra_attributes, values)
//	  $7 warning => *N (array of strings)
func parseFTAggregateMapRESP3(data map[interface{}]interface{}) (*FTAggregateResult, error) {
	result := &FTAggregateResult{
		Rows: make([]AggregateRow, 0),
	}

	for k, v := range data {

View on GitHub (pinned to 36d97525cd)

Solutions

  1. Inspect cmd.RawVal() to see the actual decoded type and content.
  2. Confirm the command sent was FT.AGGREGATE and that the server actually returned an aggregate reply.
  3. Verify protocol negotiation (Options.Protocol) matches the server reply type.
  4. Reproduce with redis-cli to localize whether the shape originates at the server or an intermediary.
Defensive patterns

Strategy: try-catch

Try / catch

res, err := cmd.Result()
if err != nil && strings.Contains(err.Error(), "unexpected response type") {
    raw, _ := cmd.RawResult()
    log.Printf("aggregate reply neither RESP3 map nor RESP2 array; raw=%v (%T)", raw, raw)
}
return err

Prevention

When it happens

Trigger: AggregateCmd.readReply reads a reply that is neither RespMap nor an []interface{}. Triggered during response decoding when the top-level type is unexpected.

Common situations: Server returned a plain error string that ReadReply surfaced as a non-array (combined with a missed error path). RESP2/RESP3 negotiation mismatch. A reply from a different command parsed as AggregateCmd. Proxy rewriting the frame.

Related errors


AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06). Data as JSON: /data/errors/8cd2b90b96f3c992.json. Report an issue: GitHub.