{"record":{"id":"abb29add6658dc92","repo":"crowdsecurity/crowdsec","slug":"s-w-abb29a","errorCode":null,"errorMessage":"%s: %w","messagePattern":"%s: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/appsec/appsec.go","lineNumber":857,"sourceCode":"\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 {\n\t\t\treturn e\n\t\t}\n\t\treturn fmt.Errorf(\"%s: %w\", phaseName, e)\n\t}\n\n\tif out.PreEval, err = buildHookList(ctx, pre, hookPreEval, patcher); err != nil {\n\t\treturn PhaseHooks{}, wrap(err)\n\t}\n\n\tif out.PostEval, err = buildHookList(ctx, post, hookPostEval, patcher); err != nil {\n\t\treturn PhaseHooks{}, wrap(err)\n\t}\n\n\tif out.OnMatch, err = buildHookList(ctx, onMatch, hookOnMatch, patcher); err != nil {\n\t\treturn PhaseHooks{}, wrap(err)\n\t}\n\n\treturn out, nil\n}\n\nfunc (wc *AppsecConfig) Load(configName string, hub *cwhub.Hub) error {","sourceCodeStart":839,"sourceCodeEnd":875,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/appsec.go#L839-L875","documentation":"buildPhaseHooks wraps any error from building the pre_eval, post_eval, or on_match hook lists with the phase name (e.g. 'pre_eval: unable to build ... hook'). The wrap is skipped when phaseName is empty (shared section). It only adds context — the root cause is always in the wrapped error.","triggerScenarios":"AppsecConfig.Build → buildPhaseHooks with a phaseName set, and buildHookList fails for that phase (bad on_success value or hook Build failure).","commonSituations":"Debugging a broken appsec-config: this prefix tells you which phase section of the YAML to inspect; combined with 676/677 it gives stage + hook + root cause.","solutions":["Use the phase prefix to jump to the matching section (pre_eval:/post_eval:/on_match:) in the appsec config","Unwrap the error chain (errors.Unwrap or %v of the full chain) to reach the root cause","Fix the offending hook per the inner error's guidance"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Walk the error chain fully","Use phase prefix to locate YAML section"],"tags":["appsec","config","error-wrapping"],"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"}