rtk-ai/rtk · critical
invalid ctest summary regex
Error message
invalid ctest summary regex
What it means
This is a panic from `.expect("invalid ctest summary regex")` on `Regex::new` inside the SUMMARY_RE LazyLock static at src/cmds/system/ctest_cmd.rs:42. SUMMARY_RE parses ctest's `NNN% tests passed, N tests failed out of N` summary line to extract failure counts. The panic indicates the pattern literal is no longer a parseable regex; it surfaces on first use of the static while filtering ctest output.
Source
Thrown at src/cmds/system/ctest_cmd.rs:42
static TEST_RE: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(
r"(?s)^\s*(?:\d+/(\d+)\s+)?Test\s+#(\d+):\s+(.+?)\s+\.{2,}\s*(?:\*{3})?\s*(.+?)\s+([\d.]+)\s+sec\s*$",
)
.expect("invalid ctest result regex")
});
static RESULT_PREFIX_RE: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r"^\s*(?:\d+/\d+\s+)?Test\s+#\d+:")
.expect("invalid ctest result prefix regex")
});
static RESULT_TERMINATOR_RE: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r"[\d.]+\s+sec\s*$").expect("invalid ctest result terminator regex")
});
static START_RE: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r"^\s*Start\s+(\d+):\s*(.*?)\s*$").expect("invalid ctest start regex")
});
static SUMMARY_RE: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r"^\s*\d+%\s+tests passed,\s+(\d+)\s+tests failed out of\s+(\d+)")
.expect("invalid ctest summary regex")
});
static TIME_RE: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r"^\s*Total Test time \(real\)\s+=\s+([\d.]+)\s+sec")
.expect("invalid ctest time regex")
});
#[derive(Debug, Clone)]
struct TestCase {
number: u32,
name: String,
status: String,
reason: Option<String>,
duration: f64,
line_index: usize,
counter_total: Option<u32>,
}
#[derive(Debug)]View on GitHub (pinned to 36788f6bd4)
Solutions
- Inspect the SUMMARY_RE literal at src/cmds/system/ctest_cmd.rs:42-43 and fix the regex parse error
- Validate the corrected pattern with regex101 (Rust flavor) or a quick unit test
- Restore the known-good pattern: r"^\s*\d+%\s+tests passed,\s+(\d+)\s+tests failed out of\s+(\d+)"
- Run the full gate: cargo fmt --all && cargo clippy --all-targets && cargo test --all
Example fix
// before (dropped closing paren on second capture group)
Regex::new(r"^\s*\d+%\s+tests passed,\s+(\d+)\s+tests failed out of\s+(\d+")
.expect("invalid ctest summary regex")
// after
Regex::new(r"^\s*\d+%\s+tests passed,\s+(\d+)\s+tests failed out of\s+(\d+)")
.expect("invalid ctest summary regex") Defensive patterns
Strategy: validation
Validate before calling
fn assert_summary_regex_valid() {
assert!(regex::Regex::new(r"^\s*\d+%\s+tests passed,\s+(\d+)\s+tests failed out of\s+(\d+)").is_ok());
} Prevention
- Test the summary parser against recorded ctest summary fixtures
- Avoid mixing pattern-format upgrades and refactors in one commit
- Add a one-line is_ok() assertion per regex static to the test suite
- Always use raw strings for regex literals in Rust
When it happens
Trigger: First pass of ctest output through the filter after SUMMARY_RE's pattern `^\s*\d+%\s+tests passed,\s+(\d+)\s+tests failed out of\s+(\d+)` was edited into invalid syntax — unbalanced group, bad escape such as `\%`-style mistakes, or a missing quantifier operand.
Common situations: Extending the summary parser for new ctest formats (editing the pattern and losing a paren), escaping confusion when a raw string is changed, or a partial revert/merge that mixes two versions of the literal.
Related errors
- invalid ctest result prefix regex
- invalid ctest result terminator regex
- invalid ctest start regex
- invalid ctest time regex
AI-assisted analysis of rtk-ai/rtk@36788f6bd4 (2026-09-03).
Data as JSON: /api/errors/4b5c4458b62890ba.
Report an issue: GitHub.