{"record":{"id":"ce8ff55f0a69635d","repo":"crowdsecurity/crowdsec","slug":"unable-to-build-s-hook-w","errorCode":null,"errorMessage":"unable to build %s hook : %w","messagePattern":"unable to build (.+?) hook : %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/appsec/appsec.go","lineNumber":836,"sourceCode":"\t\t\twc.OutOfBandOptions.RequestBodyInMemoryLimit = wc.OutOfBand.Options.RequestBodyInMemoryLimit\n\t\t}\n\n\t\twc.VariablesTracking = append(wc.VariablesTracking, wc.OutOfBand.VariablesTracking...)\n\t\twc.OutOfBand.VariablesTracking = nil\n\t}\n}\n\n// buildHookList validates and compiles a list of hooks of the given stage.\nfunc buildHookList(ctx context.Context, hooks []Hook, stage hookStage, patcher *appsecExprPatcher) ([]Hook, error) {\n\tvar compiled []Hook\n\n\tfor _, hook := range hooks {\n\t\tif hook.OnSuccess != \"\" && hook.OnSuccess != \"continue\" && hook.OnSuccess != \"break\" {\n\t\t\treturn nil, fmt.Errorf(\"invalid 'on_success' for %s hook : %s\", stage, hook.OnSuccess)\n\t\t}\n\n\t\tif err := hook.Build(ctx, stage, patcher); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to build %s hook : %w\", stage, err)\n\t\t}\n\n\t\tcompiled = append(compiled, hook)\n\t}\n\n\treturn compiled, nil\n}\n\n// buildPhaseHooks compiles pre_eval / post_eval / on_match hook lists into a\n// PhaseHooks. phaseName is only used to wrap errors (\"\" for the shared section).\nfunc buildPhaseHooks(ctx context.Context, phaseName string, pre, post, onMatch []Hook, patcher *appsecExprPatcher) (PhaseHooks, error) {\n\tvar (\n\t\tout PhaseHooks\n\t\terr error\n\t)\n\n\twrap := func(e error) error {\n\t\tif phaseName == \"\" || e == nil {","sourceCodeStart":818,"sourceCodeEnd":854,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/appsec.go#L818-L854","documentation":"buildHookList compiles every hook of a stage via hook.Build (filter/apply expr compilation, apply-rule setup). If any hook fails to build, the stage build aborts and the underlying error is wrapped with the stage name (pre_eval, post_eval, on_match). This is a wrapper: look at the wrapped error (e.g. expr compile failure) for the root cause.","triggerScenarios":"Build() → buildPhaseHooks → buildHookList where one hook's Build returns an error: invalid expr filter/apply (672/673), a referenced rule file that fails to load, or invalid hook options.","commonSituations":"An appsec rule with a bad expr filter; hook referencing a missing variable or rule; broken YAML that unmarshaled into a hook with empty/invalid fields that Build rejects.","solutions":["Look at the wrapped (%w) inner error for the real cause and fix it (usually an expr compile error)","Note the stage prefix in the message to locate the failing phase section in the YAML","Validate each hook's filter/apply expressions individually with the expr CLI or a small Go test","Bisect by commenting out hooks in that stage until the build succeeds"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Inspect the wrapped root cause","Dry-run build configs before deploy"],"tags":["appsec","config","hooks"],"backgroundTag":"invalid-config-value","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}