{"record":{"id":"193b0f27f0d63758","repo":"crowdsecurity/crowdsec","slug":"stash-d-w","errorCode":null,"errorMessage":"stash %d: %w","messagePattern":"stash (.+?): %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/parser/node.go","lineNumber":97,"sourceCode":"\tif n.Filter != \"\" && n.RunTimeFilter == nil {\n\t\treturn fmt.Errorf(\"non-empty filter %q was not compiled\", n.Filter)\n\t}\n\n\tif n.RuntimeGrok.RunTimeRegexp != nil || n.Grok.TargetField != \"\" {\n\t\tif err := n.Grok.Validate(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tfor idx, static := range n.Statics {\n\t\tif err := static.Validate(ectx); err != nil {\n\t\t\treturn fmt.Errorf(\"static %d: %w\", idx, err)\n\t\t}\n\t}\n\n\tfor idx, stash := range n.Stashes {\n\t\tif err := stash.Validate(); err != nil {\n\t\t\treturn fmt.Errorf(\"stash %d: %w\", idx, err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (n *Node) processFilter(cachedExprEnv map[string]any) (bool, error) {\n\tclog := n.Logger\n\tif n.RunTimeFilter == nil {\n\t\tclog.Trace(\"Node has no filter, enter\")\n\t\treturn true, nil\n\t}\n\n\t// Evaluate node's filter\n\toutput, err := exprhelpers.Run(n.RunTimeFilter, cachedExprEnv, clog, n.Debug)\n\tif err != nil {\n\t\tclog.Warningf(\"failed to run filter: %v\", err)\n\t\tclog.Debug(\"Event leaving node: ko\")","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/parser/node.go#L79-L115","documentation":"Wraps an error returned by validating one of a parser node's stash entries during node validation. The %d is the zero-based index of the failing stash in the node's Stashes list; the wrapped %w is the underlying validation error from stash.Validate(). It lets the developer locate which stash entry in the node definition is invalid.","triggerScenarios":"Calling node.validate() (via compile or TestParserConfigs) when a node in a parser YAML has a stash (name/expressions entry) that fails its own Validate() check — e.g. a stash with missing or malformed fields.","commonSituations":"Hub parser configs with malformed 'stash' entries, hand-edited or user-local parser files with incomplete stash definitions, or new stash schema fields not satisfied by an older parser format.","solutions":["Read the wrapped error to identify the failing field of the stash at the given index","Open the parser YAML for the node and fix the stash entry at that index","Re-run `cscli hubtool` / parser tests (TestParserConfigs) to confirm the config validates"],"exampleFix":"# before (invalid stash)\nstash:\n  - name: my_stash\n    expressions:\n      - evt.Parsed.foo\n# after (expression needs target form)\nstash:\n  - name: my_stash\n    expressions:\n      - evt.Parsed.foo == 'bar'","handlingStrategy":"validation","validationCode":"for i, stash := range node.Stashes {\n    if err := stash.Validate(); err != nil {\n        return fmt.Errorf(\"stash %d (%s): %w\", i, stash.Name, err)\n    }\n}","typeGuard":"func stashIsValid(s Stash) bool { return s.Name != \"\" && len(s.Expressions) > 0 }","tryCatchPattern":"if err := node.validate(); err != nil {\n    var cfgErr *ConfigError\n    if errors.As(err, &cfgErr) { /* fix parser YAML at reported stash index */ }\n    return err\n}","preventionTips":["Run TestParserConfigs on every custom parser before deploying","Keep stash entries complete: name plus valid expressions","Validate parser YAML with cscli hubtool before loading into production"],"tags":["parser","validation","config","yaml"],"backgroundTag":"schema-validation-failed","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"}