{"record":{"id":"673e1cd333fcb120","repo":"crowdsecurity/crowdsec","slug":"invalid-policy-q-expected-q-or-q","errorCode":null,"errorMessage":"invalid policy %q (expected %q or %q)","messagePattern":"invalid policy %q \\(expected %q or %q\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/appsec/api_validation/api_validation.go","lineNumber":38,"sourceCode":"\n// Policy controls what the validator does when it encounters a condition it\n// cannot fully validate (unknown route, method not allowed for a matched\n// path, security scheme type the WAF cannot enforce).\ntype Policy string\n\nconst (\n\t// PolicyDrop treats the condition as a validation failure.\n\tPolicyDrop Policy = \"drop\"\n\t// PolicyIgnore lets the request through as if the condition had passed.\n\tPolicyIgnore Policy = \"ignore\"\n)\n\nfunc (p Policy) validate() error {\n\tswitch p {\n\tcase PolicyDrop, PolicyIgnore:\n\t\treturn nil\n\t}\n\treturn fmt.Errorf(\"invalid policy %q (expected %q or %q)\", p, PolicyDrop, PolicyIgnore)\n}\n\n// SchemaOptions configures per-schema validation behavior. A nil *SchemaOptions\n// passed to LoadSchema means \"use defaults\" (all policies = drop, matching\n// pre-option behavior).\ntype SchemaOptions struct {\n\tOnRouteNotFound             Policy\n\tOnMethodNotAllowed          Policy\n\tOnUnsupportedSecurityScheme Policy\n}\n\nfunc (o *SchemaOptions) withDefaults() SchemaOptions {\n\tout := SchemaOptions{\n\t\tOnRouteNotFound:             PolicyDrop,\n\t\tOnMethodNotAllowed:          PolicyDrop,\n\t\tOnUnsupportedSecurityScheme: PolicyDrop,\n\t}\n\tif o == nil {","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/api_validation/api_validation.go#L20-L56","documentation":"The api_validation Policy field (used for on_route_not_found / on_method_not_allowed / on_unsupported_security_scheme appsec options) was set to a value other than the two accepted sentinels \"drop\" or \"ignore\". This is the config-validation guard in Policy.validate(); the offending value is echoed with the allowed set.","triggerScenarios":"Calling LoadSchema/SchemaOptions configuration with a Policy value other than \"drop\" or \"ignore\", e.g. a typo like \"block\" or \"deny\", triggering validate() at pkg/appsec/api_validation/api_validation.go:38.","commonSituations":"Typo in appsec API validation config; copying policy names from other WAF tooling (e.g. 'block'); casing mistakes like \"Drop\".","solutions":["Set the policy to exactly \"drop\" or \"ignore\" (lowercase).","Check the config file/value source for typos or casing issues.","Consult the SchemaOptions docs to confirm the supported policy values."],"exampleFix":"// before\nopts.Policy = \"block\"\n// after\nopts.Policy = PolicyDrop // or PolicyIgnore","handlingStrategy":"validation","validationCode":"policy := \"drop\"; if policy != \"drop\" && policy != \"ignore\" { return fmt.Errorf(\"policy must be drop or ignore, got %q\", policy) }","typeGuard":"func validPolicy(p string) bool { return p == \"drop\" || p == \"ignore\" }","tryCatchPattern":"if err := api_validation.LoadSchema(schema, opts); err != nil { if strings.Contains(err.Error(), \"invalid policy\") { return fmt.Errorf(\"check appsec config policy value: %w\", err) } return err }","preventionTips":["Use the PolicyDrop/PolicyIgnore constants instead of raw strings","Lint appsec config values against the documented enum","Watch for casing ('Drop' is invalid)"],"tags":["appsec","api-validation","config","enum"],"backgroundTag":"invalid-enum-value","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"}