go-redis/redis · error

unexpected RESP3 response type: %T

Error message

unexpected RESP3 response type: %T

What it means

Returned by AggregateCmd.readReply when the RESP3 map framing type was detected (proto.RespMap) but the parsed rawVal is not a map[interface{}]interface{}. The RESP3 FT.AGGREGATE reply is expected to be a map with keys like total_results/results/warnings; any other concrete type under a map framing is a decoding anomaly.

Solutions

  1. Inspect cmd.RawVal() to see the actual decoded type.
  2. Confirm the server genuinely speaks RESP3 and returns a map for FT.AGGREGATE (redis-cli with RESP3).
  3. Check for proxies/middleware mangling RESP3 frames; bypass to localize.
  4. If using a forked/older proto decoder, align with the version bundled by this client.
Defensive patterns

Strategy: try-catch

Try / catch

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

Prevention

When it happens

Trigger: AggregateCmd.readReply peeks RespMap then ReadReply yields something other than map[interface{}]interface{}. Triggered during RESP3 response decoding.

Common situations: A custom or older RESP3 source that encodes the map differently. A proxy rewriting RESP3 frames. A go-redis/proto version mismatch in decoding. An unexpected RESP3 sub-type landing under the map framing.

Related errors


AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06). Data as JSON: /api/errors/13ca0e578617aa50. Report an issue: GitHub.

Appendix: source

Thrown at search_commands.go:1007

func (cmd *AggregateCmd) readReply(rd *proto.Reader) (err error) {
	readType, err := rd.PeekReplyType()
	if err != nil {
		return err
	}

	// RESP3 returns a map, RESP2 returns an array
	if readType == proto.RespMap {
		// Read raw response first for backwards compatibility
		cmd.rawVal, err = rd.ReadReply()
		if err != nil {
			return err
		}
		// Parse the raw response into structured result
		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.

View on GitHub (pinned to 36d97525cd)