{"record":{"id":"d63918f9aec63950","repo":"zeroclaw-labs/zeroclaw","slug":"static-slack-token-regex-must-compile","errorCode":null,"errorMessage":"static Slack token regex must compile","messagePattern":"static Slack token regex must compile","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"info","filePath":"crates/zeroclaw-runtime/src/security/leak_detector.rs","lineNumber":202,"sourceCode":"                (Regex::new(r\"gsk_[a-zA-Z0-9]{20,}\").unwrap(), \"Groq API key\"),\n                // Google\n                (\n                    Regex::new(r\"AIza[a-zA-Z0-9_-]{35}\").unwrap(),\n                    \"Google API key\",\n                ),\n                // GitHub\n                (\n                    Regex::new(r\"gh[pousr]_[a-zA-Z0-9]{36,}\").unwrap(),\n                    \"GitHub token\",\n                ),\n                (\n                    Regex::new(r\"github_pat_[a-zA-Z0-9_]{22,}\").unwrap(),\n                    \"GitHub PAT\",\n                ),\n                // Slack\n                (\n                    Regex::new(r\"xox[baprs]-[0-9A-Za-z-]{10,}\")\n                        .expect(\"static Slack token regex must compile\"),\n                    \"Slack token\",\n                ),\n                (\n                    Regex::new(r\"xapp-[0-9A-Za-z-]{10,}\")\n                        .expect(\"static Slack app-level token regex must compile\"),\n                    \"Slack app-level token\",\n                ),\n                (\n                    Regex::new(r\"xwfp-[0-9A-Za-z-]{10,}\")\n                        .expect(\"static Slack workflow token regex must compile\"),\n                    \"Slack workflow token\",\n                ),\n                (\n                    // Rotation family: refresh tokens (`xoxe-…`) and rotated\n                    // access tokens (`xoxe.xoxb-…`, `xoxe.xoxp-…`). The base\n                    // `xox[baprs]-` class excludes `e`, and matching only the\n                    // inner `xoxb-`/`xoxp-` would leave the `xoxe.` prefix\n                    // unredacted, so cover the whole token explicitly.","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-runtime/src/security/leak_detector.rs#L184-L220","documentation":"check_api_keys() in the secret leak detector compiles its regex patterns on every call; the Slack bot/user token pattern xox[baprs]-... is a hardcoded literal, and regex literals fail to compile only through programmer error. The expect(\"static Slack token regex must compile\") is a deliberately loud assertion for that case.","triggerScenarios":"Any scan_with_protected_spans() invocation compiles this pattern; a panic means the literal regex in leak_detector.rs is syntactically invalid, e.g. someone edited it and introduced a malformed escape or unbalanced group.","commonSituations":"Contributors tuning leak-detection patterns; backports where the pattern was hand-merged and corrupted. In released builds the pattern has already been exercised by tests, so it cannot fire.","solutions":["Validate the edited pattern locally: Regex::new(r\"xox[baprs]-[0-9A-Za-z-]{10,}\") must succeed before committing.","Run the leak-detector unit tests after touching patterns.","Better: compile the patterns once in a LazyLock/OnceLock so an invalid pattern fails on first use in tests deterministically."],"exampleFix":"// before: pattern rebuilt per call, typo breaks every scan at runtime\nRegex::new(r\"xox[baprs-[0-9A-Za-z-]{10,}\").expect(\"static Slack token regex must compile\")\n\n// after: compile once, fail fast and clearly\nstatic SLACK_TOKEN: LazyLock<Regex> =\n    LazyLock::new(|| Regex::new(r\"xox[baprs]-[0-9A-Za-z-]{10,}\").expect(\"static Slack token regex must compile\"));","handlingStrategy":"validation","validationCode":"// Keep pattern edits test-covered; assert compilation in a unit test:\n#[test]\nfn leak_detector_patterns_compile() {\n    assert!(regex::Regex::new(r\"xox[baprs]-[0-9A-Za-z-]{10,}\").is_ok());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run the leak-detector tests after any pattern edit; they exercise check_api_keys end to end.","Prefer LazyLock statics over per-call Regex::new so invalid patterns fail deterministically on first use.","Validate edited regex literals in a scratch test before committing."],"tags":["rust","regex","leak-detection","invariant","static-pattern"],"backgroundTag":"regex-compilation-failed","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}