{"record":{"id":"b9f5310aad426a7c","repo":"crowdsecurity/crowdsec","slug":"averageinterval-expects-exactly-one-parameter-a-s","errorCode":null,"errorMessage":"AverageInterval expects exactly one parameter: a slice of times","messagePattern":"AverageInterval expects exactly one parameter: a slice of times","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/exprhelpers/helpers.go","lineNumber":663,"sourceCode":"\t\tlog.Errorf(\"Could not parse URI: %s\", err)\n\t\treturn ret, nil\n\t}\n\n\tparsed, err := url.ParseQuery(u.RawQuery)\n\tif err != nil {\n\t\tlog.Errorf(\"Could not parse query uri : %s\", err)\n\t\treturn ret, nil\n\t}\n\n\tmaps.Copy(ret, parsed)\n\n\treturn ret, nil\n}\n\n// func AverageInterval(times []time.Time) time.Duration\nfunc AverageInterval(params ...any) (any, error) {\n\tif len(params) != 1 {\n\t\treturn 0, errors.New(\"AverageInterval expects exactly one parameter: a slice of times\")\n\t}\n\n\tvar times []time.Time\n\n\t// Handle both []time.Time and []interface{} (from expr map function)\n\tswitch v := params[0].(type) {\n\tcase []time.Time:\n\t\ttimes = v\n\tcase []interface{}:\n\t\ttimes = make([]time.Time, len(v))\n\t\tfor i, item := range v {\n\t\t\tt, ok := item.(time.Time)\n\t\t\tif !ok {\n\t\t\t\treturn 0, fmt.Errorf(\"element at index %d is not a time.Time\", i)\n\t\t\t}\n\t\t\ttimes[i] = t\n\t\t}\n\tdefault:","sourceCodeStart":645,"sourceCodeEnd":681,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/exprhelpers/helpers.go#L645-L681","documentation":"AverageInterval is an expr-lang helper exposed to expressions that computes the mean gap between timestamps. It requires exactly one argument: a slice of time.Time values. This error is thrown when the expression passes zero arguments or more than one.","triggerScenarios":"An expr expression calls AverageInterval() with no args, or passes multiple separate args like AverageInterval(t1, t2) instead of a single slice.","commonSituations":"Writing a custom scenario expression and forgetting to wrap timestamps in a slice, e.g. using map/filter output split across arguments.","solutions":["Pass exactly one argument: a slice of times, e.g. AverageInterval(evt.Meta.timestamps)","If using expr's map(), make sure its result is passed as a single value: AverageInterval(map(t, ...))","Check the scenario expression signature against the helper docs"],"exampleFix":"// before\nAverageInterval(evt.Meta.t1, evt.Meta.t2)\n// after\nAverageInterval(map(evt.Meta.event_times, #))","handlingStrategy":"validation","validationCode":"// in scenario/expr validation\nif len(args) != 1 {\n    return errors.New(\"AverageInterval takes exactly one slice argument\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass a single slice: AverageInterval(map(times, #))","Lint/test custom scenarios with cscli test before deploying","Follow existing crowdsec scenarios using AverageInterval as reference"],"tags":["expr","scenario","crowdsec"],"backgroundTag":"missing-required-argument","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}