crowdsecurity/crowdsec · error

AverageInterval expects a slice of times

Error message

AverageInterval expects a slice of times

What it means

AverageInterval accepts the single parameter only if it is a []time.Time or an []interface{} whose elements are all time.Time. This error is thrown in the type-switch default branch when the argument is some other type (string, int, a single time.Time, etc.).

Source

Thrown at pkg/exprhelpers/helpers.go:682

	}

	var times []time.Time

	// 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

View on GitHub (pinned to 909b515798)

Solutions

  1. Ensure the argument is a slice of times: []time.Time or expr map(...) over time values
  2. Wrap a single timestamp in a slice only if you have >=2, else the next check will also fail
  3. Cast/convert fields to time.Time before calling, e.g. with parse_date helper

Example fix

// before
AverageInterval(evt.Meta.timestamp)
// after
AverageInterval([evt.Meta.timestamp, evt.Alert.GetEvents()...]) or use map() over time values
Defensive patterns

Strategy: type-guard

Validate before calling

// expr: only call with slices of times
typeOf(times) == "[]time.Time" && len(times) >= 2

Type guard

func isTimeSlice(v any) bool {
    switch t := v.(type) {
    case []time.Time:
        return true
    case []any:
        for _, e := range t {
            if _, ok := e.(time.Time); !ok {
                return false
            }
        }
        return true
    }
    return false
}

Prevention

When it happens

Trigger: Calling AverageInterval with a non-slice argument, e.g. a single time.Time, a string field, or a slice of non-time values (from expr's map without a time-producing expression).

Common situations: Scenario expression passes evt.Meta.timestamp (single time) instead of a slice; map() built strings instead of times; wrong meta field type.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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