redis/go-redis · error

redis: FT.AGGREGATE COLLECT: empty field name in Fields

Error message

redis: FT.AGGREGATE COLLECT: empty field name in Fields

What it means

The COLLECT aggregation step's FIELDS list must contain non-empty field names. buildCollectArgs validates each entry, stripping a leading '@'; an entry that is empty or only '@' names no attribute, so argument building aborts with this error before the command is sent.

Source

Thrown at search_collect.go:94

	return "@" + strings.TrimLeft(name, "@")
}

// buildCollectArgs renders a FTAggregateCollect into the reducer argument
// token list (everything after "REDUCE COLLECT <narg>", excluding AS <alias>).
// The serializer computes <narg> as len(args), which matches the COLLECT
// contract: narg counts every FIELDS/DISTINCT/SORTBY/LIMIT token.
func buildCollectArgs(o FTAggregateCollect) ([]interface{}, error) {
	args := make([]interface{}, 0, 8)

	// FIELDS (required): either * or a counted list of @-names.
	switch {
	case o.FieldsAll:
		args = append(args, "FIELDS", "*")
	case len(o.Fields) > 0:
		args = append(args, "FIELDS", len(o.Fields))
		for _, f := range o.Fields {
			if strings.TrimLeft(f, "@") == "" {
				return nil, fmt.Errorf("redis: FT.AGGREGATE COLLECT: empty field name in Fields")
			}
			args = append(args, ensureAtPrefix(f))
		}
	default:
		return nil, fmt.Errorf("redis: FT.AGGREGATE COLLECT requires FieldsAll or a non-empty Fields list")
	}

	// DISTINCT (optional, forward-compatible).
	if o.Distinct {
		args = append(args, "DISTINCT")
	}

	// SORTBY (optional). sort_narg counts each field plus its optional
	// direction token.
	if len(o.SortBy) > 0 {
		sortTokens := make([]interface{}, 0, len(o.SortBy)*2)
		for _, s := range o.SortBy {
			if strings.TrimLeft(s.FieldName, "@") == "" {

View on GitHub (pinned to c5cad058c7)

Solutions

  1. Replace empty/'@'-only entries in Fields with actual field names (with or without the '@' prefix)
  2. Filter out empty strings before constructing the Collect reducer
  3. Validate the field list at config-load time

Example fix

// before
r := redis.NewCollectReducer(redis.CollectOptions{Fields: []string{"@", "@age"}})
// after
r := redis.NewCollectReducer(redis.CollectOptions{Fields: []string{"@name", "@age"}})
Defensive patterns

Strategy: validation

Validate before calling

for _, f := range fields {
    if strings.TrimLeft(f, "@") == "" {
        return fmt.Errorf("invalid COLLECT field: %q", f)
    }
}

Prevention

When it happens

Trigger: NewCollectReducer with CollectOptions.Fields containing "" or "@"; buildCollectArgs hits strings.TrimLeft(f, "@") == "" and returns nil plus this error.

Common situations: Building COLLECT field lists programmatically from user input or config where a field was left blank; a stray '@' typo instead of a field name like '@name'.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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