rtk-ai/rtk · error

invalid nextest starting regex

Error message

invalid nextest starting regex

What it means

This panic fires when regex::Regex::new cannot compile the hardcoded nextest 'Starting' pattern (r"Starting \d+ tests? across (\d+) binar(?:y|ies)") at src/cmds/rust/cargo_cmd.rs:627-628, inside filter_cargo_nextest. The pattern is a string literal recompiled at runtime on every call, so the panic is only reachable after a developer edits the literal into an invalid regex — child output cannot trigger it. Like its sibling summary regex, it violates the repo's LazyLock rule for regex statics.

Source

Thrown at src/cmds/rust/cargo_cmd.rs:628

    }
    let mut block = header.clone();
    if !body.is_empty() {
        block.push('\n');
        block.push_str(&body.join("\n"));
    }
    failures.push(block);
    header.clear();
    body.clear();
}

/// Filter cargo nextest output - show failures + compact summary
fn filter_cargo_nextest(output: &str) -> String {
    let summary_re = regex::Regex::new(
        r"Summary \[\s*([\d.]+)s\]\s+(\d+) tests? run:\s+(\d+) passed(?:,\s+(\d+) failed)?(?:,\s+(\d+) skipped)?"
    ).expect("invalid nextest summary regex");

    let starting_re = regex::Regex::new(r"Starting \d+ tests? across (\d+) binar(?:y|ies)")
        .expect("invalid nextest starting regex");

    let mut failures: Vec<String> = Vec::new();
    let mut in_failure_block = false;
    let mut past_summary = false;
    let mut current_failure_header = String::new();
    let mut current_failure_body = Vec::new();
    let mut summary_line = String::new();
    let mut binaries: u32 = 0;
    let mut has_cancel_line = false;

    for line in output.lines() {
        let trimmed = line.trim();

        // Strip compilation noise
        if trimmed.starts_with("Compiling")
            || trimmed.starts_with("Downloading")
            || trimmed.starts_with("Downloaded")
            || trimmed.starts_with("Finished")

View on GitHub (pinned to d977e1c316)

Solutions

  1. Validate the edited literal in isolation (scratch program or `cargo test` with a compile-only test) to get the precise syntax error, then fix it at src/cmds/rust/cargo_cmd.rs:627.
  2. Hoist into `static STARTING_RE: LazyLock<Regex>` per the repo regex convention, eliminating recompilation per call.
  3. Add a unit test asserting the regex matches "Starting 42 tests across 3 binaries" so regressions fail in `cargo test`, not in production runs.

Example fix

// before (src/cmds/rust/cargo_cmd.rs:627)
let starting_re = regex::Regex::new(r"Starting \d+ tests? across (\d+) binar(?:y|ies)")
    .expect("invalid nextest starting regex");

// after
static STARTING_RE: std::sync::LazyLock<regex::Regex> = std::sync::LazyLock::new(|| {
    regex::Regex::new(r"Starting \d+ tests? across (\d+) binar(?:y|ies)")
        .expect("invalid nextest starting regex")
});

#[test]
fn nextest_starting_regex_matches() {
    assert!(STARTING_RE.is_match("Starting 42 tests across 3 binaries"));
}
Defensive patterns

Strategy: validation

Validate before calling

#[test]
fn nextest_starting_regex_compiles_and_matches() {
    let starting = regex::Regex::new(r"Starting \d+ tests? across (\d+) binar(?:y|ies)")
        .expect("invalid nextest starting regex");
    assert!(starting.is_match("Starting 42 tests across 3 binaries"));
    assert!(starting.is_match("Starting 1 test across 1 binary"));
}

Prevention

When it happens

Trigger: Any invocation that calls filter_cargo_nextest (`rtk cargo nextest` or a hooked `cargo nextest`) after the literal was made invalid — e.g. renaming the `binar(?:y|ies)` alternation to `binar(y|ies` (unbalanced paren) or escaping a metachar wrongly. Regex::new executes unconditionally before the line loop, so the process panics even for output with no 'Starting' line.

Common situations: Contributor tweaks the pattern to also match nextest's 'Starting N tests across M binaries (M features)' variant, drops a closing paren or bracket, cargo build still succeeds (pattern is runtime data), and the first `rtk cargo nextest` run panics with this message — often noticed only in CI smoke tests or by an agent proxying test runs.

Related errors


AI-assisted analysis of rtk-ai/rtk@d977e1c316 (2026-08-16). Data as JSON: /api/errors/d861c9361acc0e38. Report an issue: GitHub.