go-redis/redis · error
redis: invalid timeseries aggregator: %d
Error message
redis: invalid timeseries aggregator: %d
What it means
Returned by formatAggregatorArg when aggregator.String() returns the empty string, which occurs for any Aggregator value not covered by the switch (i.e. the Invalid zero value or an out-of-range cast). This is the single-aggregator code path in formatAggregationArgs and the shared helper.
Source
Thrown at timeseries_commands.go:208
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
}
type TSRangeOptions struct {
Latest bool
FilterByTS []int
FilterByValue []int
Count int
Align interface{}
// Deprecated: use Aggregators instead.
Aggregator Aggregator
Aggregators []Aggregator
BucketDuration int
BucketTimestamp interface{}
Empty bool
}
View on GitHub (pinned to 36d97525cd)
Solutions
- Set the Aggregator field to a valid named constant (redis.Avg, redis.Sum, etc.).
- Prefer the Aggregators slice over the deprecated single Aggregator field.
- Bounds-check any cast aggregator against [redis.Avg, redis.CountAll] before use.
Example fix
// before
opts := &redis.TSRangeOptions{Aggregator: redis.Aggregator(0)} // Invalid
client.TSRangeWithArgs(ctx, key, 0, -1, opts)
// after
opts := &redis.TSRangeOptions{Aggregators: []redis.Aggregator{redis.Avg}}
client.TSRangeWithArgs(ctx, key, 0, -1, opts) Defensive patterns
Strategy: validation
Validate before calling
func validSingleAggregator(a redis.Aggregator) error {
if a == redis.Invalid || a > redis.CountAll {
return fmt.Errorf("aggregator %d is not valid", a)
}
return nil
} Type guard
func isValidAggregator(a redis.Aggregator) bool { return a != redis.Invalid && a <= redis.CountAll } Prevention
- Migrate from the deprecated single Aggregator field to the Aggregators slice.
- Always set the aggregator explicitly rather than relying on the zero value.
- Validate cast values from external sources before assignment.
When it happens
Trigger: Passing a single Aggregator (the deprecated Aggregator field) that is either redis.Invalid or an out-of-range cast value such as redis.Aggregator(50).
Common situations: Default zero-value Aggregator left in TSOptions/TSRangeOptions when the caller intended to set one, or an integer cast from external data without validation.
Related errors
- redis: invalid timeseries aggregator at index %d: %d
- redis: invalid timeseries aggregator at index %d[%d]: %d
- redis: invalid timeseries aggregator at index %d: Invalid (%
- redis: TS.NRANGE/TS.NREVRANGE requires exactly %d aggregator
- redis: empty timeseries aggregator spec at index %d
AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06).
Data as JSON: /data/errors/f2b9ad9fb3146de1.json.
Report an issue: GitHub.