crowdsecurity/crowdsec · error

unable to run assert '%s': %w

Error message

unable to run assert '%s': %w

What it means

AssertFile in the hubtest package evaluates each line of a .assert file as an expression. If ParserAssert.Run (which compiles/evaluates the expression via expr) returns an error, the error is wrapped with the offending assertion text so the developer can see which line failed. It means the assertion expression itself could not be executed (syntax error, unknown field/function, runtime evaluation error), not that the assertion was false.

Source

Thrown at pkg/hubtest/parser_assert.go:97

	if err := p.LoadTest(testFile); err != nil {
		return fmt.Errorf("unable to load parser dump file '%s': %w", testFile, err)
	}

	scanner := bufio.NewScanner(file)
	scanner.Split(bufio.ScanLines)

	nbLine := 0

	for scanner.Scan() {
		nbLine++

		if scanner.Text() == "" {
			continue
		}

		ok, err := p.Run(scanner.Text())
		if err != nil {
			return fmt.Errorf("unable to run assert '%s': %w", scanner.Text(), err)
		}

		p.NbAssert++

		if !ok {
			log.Debugf("%s is FALSE", scanner.Text())
			failedAssert := &AssertFail{
				File:       p.File,
				Line:       nbLine,
				Expression: scanner.Text(),
				Debug:      make(map[string]string),
			}

			match := variableRE.FindStringSubmatch(scanner.Text())

			var variable string

			if len(match) == 0 {

View on GitHub (pinned to 909b515798)

Solutions

  1. Run the failing assertion text through EvalExpression directly to get the underlying expr compile/runtime error and fix the expression syntax
  2. Verify every field referenced in the assertion exists in the event map produced by the parser (add debug dump of the evt map)
  3. Regenerate the assertions with cscli hubtest auto-generate if the parser output changed
  4. Check the expr-lang/library version for syntax incompatibilities

Example fix

// before (assert file)
Alert.GetScope() == 'ip' and Alert.GetValue == '1.2.3.4'
// after
Alert.GetScope() == 'ip' and Alert.GetValue() == '1.2.3.4'
Defensive patterns

Strategy: try-catch

Validate before calling

// validate assertions before running
lines := strings.Split(string(assertContent), "\n")
for _, l := range lines {
    l = strings.TrimSpace(l)
    if l == "" { continue }
    if _, err := p.EvalExpression(l); err != nil {
        return fmt.Errorf("invalid assertion %q: %w", l, err)
    }
}

Type guard

func isBoolOutput(out interface{}) bool {
    _, ok := out.(bool)
    return ok
}

Try / catch

if err := p.AssertFile(assertFile, snapFilePath, testFile); err != nil {
    var exprErr interface{ Unwrap() error }
    if errors.As(err, &wrapped) {
        log.Errorf("assertion failed: %v (cause: %v)", err, errors.Unwrap(err))
    }
    return err
}

Prevention

When it happens

Trigger: Calling AssertFile (directly or via RunWithLogFile) on an assert file containing a line that expr fails to compile or evaluate: malformed expression, reference to a field absent from the event map, or a runtime type error inside the expression.

Common situations: Hand-edited .assert files in hub tests with typos; assertions referencing parser fields that were renamed or no longer produced; expr syntax unsupported by the expr-lang version in use; empty/whitespace-only lines are skipped, but stray characters (trailing commas, unmatched quotes) are not.

Related errors


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