{"record":{"id":"dd9969e983a74e16","repo":"gitleaks/gitleaks","slug":"must-contain-at-least-one-check-for-commits-path","errorCode":null,"errorMessage":"must contain at least one check for: commits, paths, regexes, or stopwords","messagePattern":"must contain at least one check for: commits, paths, regexes, or stopwords","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/allowlist.go","lineNumber":80,"sourceCode":"\t// commitMap is a normalized version of Commits, used for efficiency purposes.\n\t// TODO: possible optimizations so that both short and long hashes work.\n\tcommitMap    map[string]struct{}\n\tregexPat     *regexp.Regexp\n\tpathPat      *regexp.Regexp\n\tstopwordTrie *ahocorasick.Trie\n}\n\nfunc (a *Allowlist) Validate() error {\n\tif a.validated {\n\t\treturn nil\n\t}\n\n\t// Disallow empty allowlists.\n\tif len(a.Commits) == 0 &&\n\t\tlen(a.Paths) == 0 &&\n\t\tlen(a.Regexes) == 0 &&\n\t\tlen(a.StopWords) == 0 {\n\t\treturn errors.New(\"must contain at least one check for: commits, paths, regexes, or stopwords\")\n\t}\n\n\t// Deduplicate commits and stopwords.\n\tif len(a.Commits) > 0 {\n\t\tuniqueCommits := make(map[string]struct{})\n\t\tfor _, commit := range a.Commits {\n\t\t\t// Commits are case-insensitive.\n\t\t\tuniqueCommits[strings.TrimSpace(strings.ToLower(commit))] = struct{}{}\n\t\t}\n\t\ta.Commits = maps.Keys(uniqueCommits)\n\t\ta.commitMap = uniqueCommits\n\t}\n\tif len(a.StopWords) > 0 {\n\t\tuniqueStopwords := make(map[string]struct{})\n\t\tfor _, stopWord := range a.StopWords {\n\t\t\tuniqueStopwords[strings.ToLower(stopWord)] = struct{}{}\n\t\t}\n","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/gitleaks/gitleaks/blob/b58d3f102cf3a2c84cb7f923d05c25c9b1aed84b/config/allowlist.go#L62-L98","documentation":"Every allowlist in a gitleaks config must contain at least one matching criterion: commits, paths, regexes, or stopwords. Allowlist.Validate() rejects fully-empty allowlists because an allowlist with no criteria would either match nothing (useless) or, if the condition logic were inverted, suppress everything. This fires while parsing [[allowlists]] or [[rules.allowlists]] blocks during config load.","triggerScenarios":"Declaring [[allowlists]] with only a description (or only matchCondition) and no commits/paths/regexes/stopwords; the same for a [[rules.allowlists]] table under a rule. parseAllowlist -> Validate() sees all four slices empty and returns this error, wrapped as '[[allowlists]] must contain at least one check...'.","commonSituations":"Starting an allowlist block as a placeholder intending to fill it later; YAML/TOML indentation mistakes that detach the keys from the allowlist table so they parse as empty; deleting the last criterion during cleanup; upgrading configs where a typo'd key name (e.g. stopwords vs stopWords) silently yields an empty slice.","solutions":["Add at least one criterion to the allowlist, e.g. a path regex: paths = [['''\\.md$''']].","If the allowlist is not needed, delete the whole [[allowlists]] or [[rules.allowlists]] block instead of leaving it empty.","Check key spelling and table nesting: keys must be commits, paths, regexes, stopwords directly under the allowlist table.","Run gitleaks with --verbose or use `gitleaks detect --config-path=... --no-git` on a tiny repo to smoke-test the config after edits."],"exampleFix":"# before (TOML)\n[[allowlists]]\ndescription = \"ignore docs\"\n\n# after (TOML)\n[[allowlists]]\ndescription = \"ignore docs\"\npaths = ['''\\.md$''']","handlingStrategy":"validation","validationCode":"# python: catch empty allowlist tables before running gitleaks\nimport tomllib\n\ncfg = tomllib.load(open(\"gitleaks.toml\", \"rb\"))\nfor name, als in [(\"allowlists\", cfg.get(\"allowlists\", []))] + [\n    (f\"rules[{i}].allowlists\", r.get(\"allowlists\", [])) for i, r in enumerate(cfg.get(\"rules\", []))\n]:\n    for j, a in enumerate(als):\n        if not any(a.get(k) for k in (\"commits\", \"paths\", \"regexes\", \"stopwords\")):\n            raise SystemExit(f\"empty allowlist: {name}[{j}] has no commits/paths/regexes/stopwords\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never commit placeholder allowlist blocks; add criteria or delete the block.","Validate the TOML in CI (e.g. with the snippet above) before any scan step.","Double-check key spelling: commits, paths, regexes, stopwords."],"tags":["gitleaks","config","allowlist","toml","validation"],"backgroundTag":null,"analyzedSha":"b58d3f102cf3a2c84cb7f923d05c25c9b1aed84b","analyzedAt":"2026-08-15T22:17:28.846Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}