zeroclaw-labs/zeroclaw · info

static Slack token regex must compile

Error message

static Slack token regex must compile

What it means

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.

Source

Thrown at crates/zeroclaw-runtime/src/security/leak_detector.rs:202

                (Regex::new(r"gsk_[a-zA-Z0-9]{20,}").unwrap(), "Groq API key"),
                // Google
                (
                    Regex::new(r"AIza[a-zA-Z0-9_-]{35}").unwrap(),
                    "Google API key",
                ),
                // GitHub
                (
                    Regex::new(r"gh[pousr]_[a-zA-Z0-9]{36,}").unwrap(),
                    "GitHub token",
                ),
                (
                    Regex::new(r"github_pat_[a-zA-Z0-9_]{22,}").unwrap(),
                    "GitHub PAT",
                ),
                // Slack
                (
                    Regex::new(r"xox[baprs]-[0-9A-Za-z-]{10,}")
                        .expect("static Slack token regex must compile"),
                    "Slack token",
                ),
                (
                    Regex::new(r"xapp-[0-9A-Za-z-]{10,}")
                        .expect("static Slack app-level token regex must compile"),
                    "Slack app-level token",
                ),
                (
                    Regex::new(r"xwfp-[0-9A-Za-z-]{10,}")
                        .expect("static Slack workflow token regex must compile"),
                    "Slack workflow token",
                ),
                (
                    // Rotation family: refresh tokens (`xoxe-…`) and rotated
                    // access tokens (`xoxe.xoxb-…`, `xoxe.xoxp-…`). The base
                    // `xox[baprs]-` class excludes `e`, and matching only the
                    // inner `xoxb-`/`xoxp-` would leave the `xoxe.` prefix
                    // unredacted, so cover the whole token explicitly.

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Validate the edited pattern locally: Regex::new(r"xox[baprs]-[0-9A-Za-z-]{10,}") must succeed before committing.
  2. Run the leak-detector unit tests after touching patterns.
  3. Better: compile the patterns once in a LazyLock/OnceLock so an invalid pattern fails on first use in tests deterministically.

Example fix

// before: pattern rebuilt per call, typo breaks every scan at runtime
Regex::new(r"xox[baprs-[0-9A-Za-z-]{10,}").expect("static Slack token regex must compile")

// after: compile once, fail fast and clearly
static SLACK_TOKEN: LazyLock<Regex> =
    LazyLock::new(|| Regex::new(r"xox[baprs]-[0-9A-Za-z-]{10,}").expect("static Slack token regex must compile"));
Defensive patterns

Strategy: validation

Validate before calling

// Keep pattern edits test-covered; assert compilation in a unit test:
#[test]
fn leak_detector_patterns_compile() {
    assert!(regex::Regex::new(r"xox[baprs]-[0-9A-Za-z-]{10,}").is_ok());
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/d63918f9aec63950. Report an issue: GitHub.