redis/go-redis · error

unexpected search result format

Error message

unexpected search result format

What it means

parseFTSearch received an empty array for an FT.SEARCH reply (RESP2 path). A well-formed reply always has at least one element — the total-results integer — so zero elements means the response shape is not what this library expects.

Source

Thrown at search_commands.go:2608

		val = make([]SpellCheckResult, len(cmd.val))
		for i, result := range cmd.val {
			val[i] = SpellCheckResult{
				Term: result.Term,
			}
			if result.Suggestions != nil {
				val[i].Suggestions = slices.Clone(result.Suggestions)
			}
		}
	}
	return &FTSpellCheckCmd{
		baseCmd: cmd.cloneBaseCmd(),
		val:     val,
	}
}

func parseFTSearch(data []interface{}, noContent, withScores, withPayloads, withSortKeys bool) (FTSearchResult, error) {
	if len(data) < 1 {
		return FTSearchResult{}, fmt.Errorf("unexpected search result format")
	}

	total, ok := data[0].(int64)
	if !ok {
		return FTSearchResult{}, fmt.Errorf("invalid total results format")
	}

	var results []Document
	for i := 1; i < len(data); {
		docID, ok := data[i].(string)
		if !ok {
			return FTSearchResult{}, fmt.Errorf("invalid document ID format")
		}

		doc := Document{
			ID:     docID,
			Fields: make(map[string]string),
		}

View on GitHub (pinned to c5cad058c7)

Solutions

  1. Inspect the raw reply to confirm the server really sent an empty array
  2. Remove/fix proxies or hooks that rewrite command replies
  3. Confirm the target is RediSearch (FT.INFO) and versions are compatible
  4. Check AddHook implementations aren't replacing cmd replies with empty slices

Example fix

// before: assuming reply is fine
res, _ := rdb.FTSearch(ctx, "idx", "query").Result()

// after: log raw reply on parse failure
res, err := rdb.FTSearch(ctx, "idx", "query").Result()
if err != nil {
	log.Printf("ftsearch: %v", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the search index exists before querying
if err := rdb.FTInfo(ctx, index).Err(); err != nil {
	return fmt.Errorf("index missing: %w", err)
}

Type guard

func looksLikeFTSearchReply(v interface{}) bool {
	slice, ok := v.([]interface{})
	return ok && len(slice) >= 1
}

Try / catch

res, err := rdb.FTSearch(ctx, "idx", q).Result()
if err != nil {
	if strings.Contains(err.Error(), "unexpected search result format") {
		log.Printf("malformed FT.SEARCH reply (proxy/server issue): %v", err)
		return emptyResult, nil
	}
	return err
}

Prevention

When it happens

Trigger: FTSearch with RESP2 (Protocol: 2) when the server/proxy returns an empty array instead of [total, id, fields, ...]; a fault-injecting proxy truncating replies; custom middleware returning an empty []interface{}.

Common situations: Proxy/middleware mangling FT.SEARCH responses; pointing at a non-RediSearch server; tests with truncated mock replies.

Related errors


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