crowdsecurity/crowdsec · error
non-empty filter %q was not compiled
Error message
non-empty filter %q was not compiled
What it means
Node.validate() enforces that any node with a non-empty Filter has already had that expression compiled into RunTimeFilter. If Filter is set but RunTimeFilter is nil, the compile step was skipped or failed silently, so validation rejects the node to prevent runtime evaluation of an uncompiled expression.
Source
Thrown at pkg/parser/node.go:80
child := Node{NodeConfig: subNodes[i]}
child.initRuntimeChildrenFromConfig()
n.LeavesNodes[i] = child
}
}
func (n *Node) validate(ectx EnricherCtx) error {
// stage is being set automagically
if n.Stage == "" {
return errors.New("stage needs to be an existing stage")
}
/* "" behaves like continue */
if n.OnSuccess != "continue" && n.OnSuccess != "next_stage" && n.OnSuccess != "" {
return fmt.Errorf("onsuccess %q not continue,next_stage", n.OnSuccess)
}
if n.Filter != "" && n.RunTimeFilter == nil {
return fmt.Errorf("non-empty filter %q was not compiled", n.Filter)
}
if n.RuntimeGrok.RunTimeRegexp != nil || n.Grok.TargetField != "" {
if err := n.Grok.Validate(); err != nil {
return err
}
}
for idx, static := range n.Statics {
if err := static.Validate(ectx); err != nil {
return fmt.Errorf("static %d: %w", idx, err)
}
}
for idx, stash := range n.Stashes {
if err := stash.Validate(); err != nil {
return fmt.Errorf("stash %d: %w", idx, err)
}View on GitHub (pinned to 909b515798)
Solutions
- Ensure node.Compile()/the compilation stage runs before validate(); fix the calling order in the loader.
- If constructing nodes in code or tests, explicitly compile the filter expression with exprhelpers options before validating.
- If the filter failed to compile earlier, fix the underlying expression error surfaced by the compile step.
Example fix
// before
node := &Node{Filter: "evt.Parsed.x == '1'"}
node.Validate()
// after
node := &Node{Filter: "evt.Parsed.x == '1'"}
if err := node.Compile(pctx); err != nil { return err }
if err := node.Validate(ectx); err != nil { return err } Defensive patterns
Strategy: type-guard
Validate before calling
if node.Filter != "" && node.RunTimeFilter == nil {
// compile before validating
if err := node.Compile(pctx); err != nil { return err }
} Type guard
func filterCompiled(n *parsers.Node) bool {
return n.Filter == "" || n.RunTimeFilter != nil
} Try / catch
if !filterCompiled(node) {
if err := node.Compile(pctx); err != nil { return err }
}
if err := node.Validate(ectx); err != nil { return err } Prevention
- Always route node construction through the loader's compile stage before validation.
- In tests/harnesses, call Compile() before Validate() on hand-built nodes.
- Never set Filter directly on a node after compilation.
When it happens
Trigger: validate() sees n.Filter != "" while n.RunTimeFilter == nil — the filter expression was never compiled (e.g. compile step bypassed, or filter present but compilation returned nil on some path).
Common situations: Programmatically constructed nodes (or test harnesses) that set Filter without calling the expression compilation step; config plumbing bugs where compile() wasn't invoked before validate().
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- filter is mandatory for non-IP, non-Range scope
- while compiling grok's expression: %w
- onsuccess %q not continue,next_stage
- static %d: %w
- failed to compile node in '%s' : %s
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/1c8c65ff4411ff5e.
Report an issue: GitHub.