crowdsecurity/crowdsec · warning

need at least two times to calculate an average interval

Error message

need at least two times to calculate an average interval

What it means

After coercing the argument to a slice of times, AverageInterval needs at least two timestamps to compute an interval. With fewer than two it returns this error since an average gap is undefined for 0 or 1 points.

Source

Thrown at pkg/exprhelpers/helpers.go:686

	// Handle both []time.Time and []interface{} (from expr map function)
	switch v := params[0].(type) {
	case []time.Time:
		times = v
	case []interface{}:
		times = make([]time.Time, len(v))
		for i, item := range v {
			t, ok := item.(time.Time)
			if !ok {
				return 0, fmt.Errorf("element at index %d is not a time.Time", i)
			}
			times[i] = t
		}
	default:
		return 0, errors.New("AverageInterval expects a slice of times")
	}

	if len(times) < 2 {
		return 0, errors.New("need at least two times to calculate an average interval")
	}

	// Sort times in ascending order
	sort.Slice(times, func(i, j int) bool {
		return times[i].Before(times[j])
	})

	var total time.Duration
	for i := 1; i < len(times); i++ {
		total += times[i].Sub(times[i-1])
	}

	average := time.Duration(int64(total) / int64(len(times)-1))
	return average, nil
}

// func MedianInterval(times []time.Time) (time.Duration, error)
func MedianInterval(params ...any) (any, error) {

View on GitHub (pinned to 909b515798)

Solutions

  1. Ensure the expression only runs when at least 2 events are in the bucket (condition on len(bucket) >= 2)
  2. Guard the input: only call AverageInterval when the slice length is >= 2
  3. Use an if/condition in the scenario so single-event evaluations don't invoke the helper

Example fix

// guard before calling
len(times) >= 2 ? AverageInterval(times) : 0
Defensive patterns

Strategy: validation

Validate before calling

// expr guard
len(times) >= 2 && AverageInterval(times)

Type guard

func hasAtLeastTwoTimes(times []time.Time) bool { return len(times) >= 2 }

Prevention

When it happens

Trigger: Expression passes a slice with 0 or 1 time.Time elements, e.g. a single-event scenario bucket or empty map() result.

Common situations: Scenario triggers on the first matching event before a bucket has accumulated two events; filter removed all but one timestamp; empty meta list.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/3f8b7b792afab840. Report an issue: GitHub.