crowdsecurity/crowdsec · error

while running expression %s: %w

Error message

while running expression %s: %w

What it means

EvaluateProfile runs each profile filter expression against an Alert using exprhelpers.Run. If the expression engine itself fails at runtime (not merely returning false) — e.g. a type error evaluating a field, nil dereference in the expr VM, or an environment problem — the error is wrapped as 'while running expression <filter>: ...' and EvaluateProfile returns no decisions.

Source

Thrown at pkg/csprofiles/csprofiles.go:181

	return decisions, nil
}

// EvaluateProfile is going to evaluate an Alert against a profile to generate Decisions
func (profile *Runtime) EvaluateProfile(alert *models.Alert) ([]*models.Decision, bool, error) {
	var decisions []*models.Decision

	matched := false

	for eIdx, expression := range profile.RuntimeFilters {
		debugProfile := false
		if profile.Cfg.Debug != nil && *profile.Cfg.Debug {
			debugProfile = true
		}

		output, err := exprhelpers.Run(expression, map[string]interface{}{"Alert": alert}, profile.Logger, debugProfile)
		if err != nil {
			profile.Logger.Warningf("failed to run profile expr for %s: %v", profile.Cfg.Name, err)
			return nil, matched, fmt.Errorf("while running expression %s: %w", profile.Cfg.Filters[eIdx], err)
		}

		switch out := output.(type) {
		case bool:
			if out {
				matched = true
				/*the expression matched, create the associated decision*/
				subdecisions, err := profile.GenerateDecisionFromProfile(alert)
				if err != nil {
					return nil, matched, fmt.Errorf("while generating decision from profile %s: %w", profile.Cfg.Name, err)
				}

				decisions = append(decisions, subdecisions...)
			} else {
				profile.Logger.Debugf("Profile %s filter is unsuccessful", profile.Cfg.Name)

				if profile.Cfg.OnFailure == "break" {
					break

View on GitHub (pinned to 909b515798)

Solutions

  1. Read the wrapped inner error from the log line 'failed to run profile expr' to identify the failing sub-expression.
  2. Validate the filter expr against a real Alert payload with debug enabled (CROWDSEC_DEBUG or debug: true).
  3. Fix type mismatches in the filter (quote strings, cast numbers).
  4. Update expressions to match the current models.Alert schema after upgrading CrowdSec.

Example fix

// before (profiles.yaml filter)
filter: Alert.Source.IP == 1.2.3.4
// after
filter: "Alert.Source.IP in ['1.2.3.4']"
Defensive patterns

Strategy: try-catch

Validate before calling

// compile-check filters up front
for _, f := range profile.Filters {
    if _, err := expr.Compile(f, exprhelpers.GetExprOptions(map[string]interface{}{"Alert": &models.Alert{}})...); err != nil {
        return fmt.Errorf("invalid filter %q: %w", f, err)
    }
}

Try / catch

decisions, matched, err := profile.EvaluateProfile(alert)
if err != nil {
    log.Warnf("profile evaluation failed, no decisions applied: %v", err)
    return
}

Prevention

When it happens

Trigger: Calling EvaluateProfile with a profile whose filter compiles but fails at evaluation: accessing a nil Alert field in a way expr can't handle, applying an operator to mismatched types (e.g. comparing string to int), or a registered helper panicking/erroring at runtime.

Common situations: Filters written against an older Alert schema (field renamed/moved); expressions using Regexp() or File() helpers whose registration failed; alerts missing fields the filter assumes (e.g. nil Event whitelist entry).

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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