zeroclaw-labs/zeroclaw · critical

static Slack rotation token regex must compile

Error message

static Slack rotation token regex must compile

What it means

Same compile-time invariant as the other leak-detector patterns: check_api_keys hard-compiles the Slack rotation-family regex covering refresh tokens (`xoxe-...`) and rotated access tokens (`xoxe.xoxb-...`, `xoxe.xoxp-...`). The .expect() can only fire when the pattern literal itself is invalid, because the string is a constant with no runtime input.

Source

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

                ),
                (
                    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.
                    Regex::new(r"xoxe(?:-[0-9A-Za-z-]{10,}|\.xox[bp]-[0-9A-Za-z-]{10,})")
                        .expect("static Slack rotation token regex must compile"),
                    "Slack refresh/rotated token",
                ),
                // Generic
                (
                    Regex::new(r#"api[_-]?key[=:]\s*['"]*[a-zA-Z0-9_-]{20,}"#).unwrap(),
                    "Generic API key",
                ),
            ]
        });

        for (regex, name) in regexes {
            collect_regex_redactions(
                content,
                regex,
                protected_spans,
                name,
                "[REDACTED_API_KEY]",
                patterns,

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Restore the pattern to a valid form, e.g. `xoxe(?:-[0-9A-Za-z-]{10,}|\.xox[bp]-[0-9A-Za-z-]{10,})`, then run `cargo test -p zeroclaw-runtime`
  2. Compile the edited pattern standalone with `regex::Regex::new` in a scratch test to locate the syntax error
  3. Add a unit test that compiles every pattern in the table so regressions fail in CI instead of at scan time

Example fix

// before
Regex::new(r"xoxe(?:-[0-9A-Za-z-]{10,}|\.xox[bp-[0-9A-Za-z-]{10,})") // group broken
    .expect("static Slack rotation token regex must compile"),

// after
Regex::new(r"xoxe(?:-[0-9A-Za-z-]{10,}|\.xox[bp]-[0-9A-Za-z-]{10,})")
    .expect("static Slack rotation token regex must compile"),
Defensive patterns

Strategy: validation

Validate before calling

#[test]
fn rotation_pattern_compiles() {
    regex::Regex::new(r"xoxe(?:-[0-9A-Za-z-]{10,}|\.xox[bp]-[0-9A-Za-z-]{10,})")
        .expect("static Slack rotation token regex must compile");
}

Prevention

When it happens

Trigger: The rotation-family pattern `xoxe(?:-[0-9A-Za-z-]{10,}|\.xox[bp]-[0-9A-Za-z-]{10,})` is edited into an invalid regex (for example a broken group or missing brace) and any leak scan runs, constructing the pattern table and panicking.

Common situations: Extending the detector to new `xoxe` token shapes; merging divergent edits to the pattern table; syntax slips in the alternation group during copy-paste.

Related errors


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