go-redis/redis · error

redis: invalid timeseries aggregator at index

Error message

redis: invalid timeseries aggregator at index %d: Invalid (%d)

What it means

Returned by formatAggregationArgs when the Aggregators slice contains the zero-value Aggregator constant Invalid (0). This indicates the caller built a multi-aggregator spec but left one element unset. The message reports the slice index and the Invalid value so the offending element can be located.

Solutions

  1. Ensure every element of the Aggregators slice is a valid aggregator (Avg, Sum, Min, Max, Range, Count, First, Last, StdP, StdS, VarP, VarS, Twa, CountNaN, CountAll).
  2. Filter out zero/Invalid values before passing the slice: aggregators = slices.DeleteFunc(aggregators, func(a redis.Aggregator) bool { return a == redis.Invalid }).
  3. If appending conditionally, only append when the aggregator is valid.

Example fix

// before
opts := &redis.TSRangeOptions{Aggregators: []redis.Aggregator{redis.Avg, redis.Invalid}}
client.TSRangeWithArgs(ctx, key, 0, -1, opts)

// after
opts := &redis.TSRangeOptions{Aggregators: []redis.Aggregator{redis.Avg, redis.Sum}}
client.TSRangeWithArgs(ctx, key, 0, -1, opts)
Defensive patterns

Strategy: validation

Validate before calling

func validAggregators(aggs []redis.Aggregator) error {
    for i, a := range aggs {
        if a == redis.Invalid {
            return fmt.Errorf("aggregator at index %d is Invalid", i)
        }
    }
    return nil
}

Type guard

func isValidAggregator(a redis.Aggregator) bool { return a != redis.Invalid && a <= redis.CountAll }

Prevention

When it happens

Trigger: Calling TSRangeWithArgs/TSMRangeWithArgs/etc. with Aggregators containing an explicit redis.Invalid or an element of a pre-allocated slice that was never assigned a real aggregator (e.g. make([]redis.Aggregator, 3) with only two filled).

Common situations: Dynamically building an Aggregators slice with append/make where a branch fails to set a value, or copying from a source that uses 0 as a placeholder.

Related errors


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

Appendix: source

Thrown at timeseries_commands.go:193

func formatAggregationArgs(aggregator Aggregator, aggregators []Aggregator) (string, int, error) {
	if aggregator != Invalid && len(aggregators) > 0 {
		return "", 0, errTSAggregationConflict
	}
	if len(aggregators) == 0 {
		if aggregator == Invalid {
			return "", 0, nil
		}
		aggregationArg, err := formatAggregatorArg(aggregator)
		if err != nil {
			return "", 0, err
		}
		return aggregationArg, 1, nil
	}

	parts := make([]string, len(aggregators))
	for i, agg := range aggregators {
		if agg == Invalid {
			return "", 0, fmt.Errorf("redis: invalid timeseries aggregator at index %d: Invalid (%d)", i, agg)
		}
		aggregationArg, err := formatAggregatorArg(agg)
		if err != nil {
			return "", 0, fmt.Errorf("redis: invalid timeseries aggregator at index %d: %d", i, agg)
		}
		parts[i] = aggregationArg
	}

	return strings.Join(parts, ","), len(parts), nil
}

func formatAggregatorArg(aggregator Aggregator) (string, error) {
	aggregationArg := aggregator.String()
	if aggregationArg == "" {
		return "", fmt.Errorf("redis: invalid timeseries aggregator: %d", aggregator)
	}
	return aggregationArg, nil
}

View on GitHub (pinned to 36d97525cd)