{"record":{"id":"e59de989209e75a1","repo":"crowdsecurity/crowdsec","slug":"no-match-value-defined","errorCode":null,"errorMessage":"no match value defined","messagePattern":"no match value defined","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/appsec/appsec_rule/appsec_rule.go","lineNumber":61,"sourceCode":"\tAnd       []CustomRule `yaml:\"and,omitempty\"`\n\tOr        []CustomRule `yaml:\"or,omitempty\"`\n\n\tBodyType string `yaml:\"body_type,omitempty\"`\n}\n\n// Convert renders the rule; ruleIndex is its position in the collection, used\n// to keep ids unique across rules that share identical leaves.\nfunc (v *CustomRule) Convert(ruleType string, appsecRuleName string, appsecRuleDescription string, ruleIndex int) (string, []uint32, error) {\n\tif v.Zones == nil && v.And == nil && v.Or == nil {\n\t\treturn \"\", nil, errors.New(\"no zones defined\")\n\t}\n\n\tif v.Match.Type == \"\" && v.And == nil && v.Or == nil {\n\t\treturn \"\", nil, errors.New(\"no match type defined\")\n\t}\n\n\tif v.Match.Value == \"\" && v.And == nil && v.Or == nil {\n\t\treturn \"\", nil, errors.New(\"no match value defined\")\n\t}\n\n\tswitch ruleType {\n\tcase ModsecurityRuleType:\n\t\tr := ModsecurityRule{}\n\t\treturn r.Build(v, appsecRuleName, appsecRuleDescription, ruleIndex)\n\tdefault:\n\t\treturn \"\", nil, fmt.Errorf(\"unknown rule format '%s'\", ruleType)\n\t}\n}\n","sourceCodeStart":43,"sourceCodeEnd":72,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/appsec_rule/appsec_rule.go#L43-L72","documentation":"CustomRule.Convert requires a non-empty match value for leaf rules. A rule that declares zones and a match type but leaves `match.value` empty cannot be compiled into a concrete detection rule, so Convert rejects it. Like the other Convert checks, it is skipped when the rule has `and`/`or` children.","triggerScenarios":"Defining `zones:` and `match.type:` but omitting `match.value:` (or the value being an empty string after variable/interpolation expansion), then calling Convert during collection load.","commonSituations":"A YAML template where the value field was left blank; environment/variable substitution producing an empty string; copy-pasting a rule skeleton without filling in the value.","solutions":["Provide a match value, e.g. `match: {type: contains, value: /wp-admin}`","If the value comes from a variable, ensure it is set and non-empty at load time","For regex rules, supply the pattern in match.value"],"exampleFix":"// before\n- zones:\n    - URI\n  match:\n    type: contains\n\n// after\n- zones:\n    - URI\n  match:\n    type: contains\n    value: /wp-admin","handlingStrategy":"validation","validationCode":"if rule.Match.Type != \"\" && rule.Match.Value == \"\" {\n    return fmt.Errorf(\"rule %q: match.value must not be empty\", rule.Name)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never leave match.value blank in rule templates; fail fast on empty interpolated variables"],"tags":["appsec","rules","validation"],"backgroundTag":"missing-required-config-field","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"}