redis/go-redis · error

invalid result item format

Error message

invalid result item format

What it means

Within FT.HYBRID results, each item should be either a RESP3 map or a RESP2 flat key/value array. If an item is neither (e.g. a scalar or nested unexpected type), the parser cannot extract fields and returns this error. It means one result row arrived in an unrecognized shape.

Source

Thrown at search_commands.go:3098

			continue
		}

		// Try parsing as map[interface{}]interface{} (alternative RESP3 format)
		if rawMap, ok := item.(map[interface{}]interface{}); ok {
			itemMap := make(map[string]interface{})
			for k, v := range rawMap {
				if keyStr, ok := k.(string); ok {
					itemMap[keyStr] = v
				}
			}
			results = append(results, itemMap)
			continue
		}

		// Fall back to array format (RESP2 format - key-value pairs)
		itemData, ok := item.([]interface{})
		if !ok {
			return FTHybridResult{}, nil, fmt.Errorf("invalid result item format")
		}

		itemMap := make(map[string]interface{})
		for i := 0; i < len(itemData); i += 2 {
			if i+1 < len(itemData) {
				key, ok := itemData[i].(string)
				if !ok {
					return FTHybridResult{}, nil, fmt.Errorf("invalid item key format")
				}
				itemMap[key] = itemData[i+1]
			}
		}
		results = append(results, itemMap)
	}

	// Optional warnings; accept both "warning" (as FT.SEARCH/FT.AGGREGATE) and "warnings".
	var warnings []string
	warningsData, ok := resultMap["warning"].([]interface{})

View on GitHub (pinned to c5cad058c7)

Solutions

  1. Verify with a raw reply dump (hook/MONITOR) what type the offending row is
  2. Remove any middleware that transforms individual result rows
  3. Align server and go-redis versions on the FT.HYBRID reply contract
  4. Fix mocks so each result item is map[interface{}]interface{} or a flat []interface{}

Example fix

// before
"results": []interface{}{"corrupt-row"}
// after
"results": []interface{}{[]interface{}{"id", "doc1"}}
Defensive patterns

Strategy: type-guard

Validate before calling

// validate one known-good hybrid call before exposing the feature
if _, err := rdb.FTHybrid(ctx, "idx", "*", opts).Result(); err != nil { /* disable feature */ }

Type guard

func isResultItem(item interface{}) bool {
    switch item.(type) {
    case map[interface{}]interface{}, []interface{}:
        return true
    }
    return false
}

Try / catch

res, _, err := hybridCmd.Result()
if err != nil && strings.Contains(err.Error(), "invalid result item format") {
    // dump raw reply via hook and report; treat as upstream incompatibility
    return ErrMalformedReply
}

Prevention

When it happens

Trigger: Calling FTHybrid when an element of the "results" array is neither map-like nor []interface{} — typically due to a server/proxy producing corrupted or non-standard rows.

Common situations: RESP-transforming proxies or compression layers altering row types; exotic server builds; malformed mock data in tests.

Related errors


AI-assisted analysis of redis/go-redis@c5cad058c7 (2026-09-01). Data as JSON: /api/errors/c42b20c6ba811828. Report an issue: GitHub.