rtk-ai/rtk · error

valid regex

Error message

valid regex

What it means

This is a LazyLock static initialization for the binlog fallback error-line regex. `.expect("valid regex")` panics (not a recoverable error) if the hard-coded pattern fails to compile — which for the shipped pattern only happens in a corrupted build where the literal was modified.

Solutions

  1. Verify the regex literal in src/cmds/dotnet/binlog.rs compiles (test it in regex101 with the regex crate syntax).
  2. Revert any local modifications to FALLBACK_ERROR_LINE_RE.
  3. Rebuild from a clean checkout: cargo clean && cargo build.

Example fix

// before
Regex::new(r"(?mi)^.+\(\d+,\d+\):\s*error(?:\s+[A-Za-z]{2,}\d{3,})?(?:\s*:.*)?$").expect("valid regex") // edited literal broke it
// after
restore the original literal, or validate: Regex::new(PATTERN)? in a test
Defensive patterns

Strategy: fallback

Try / catch

// statics cannot be caught; guard at build time
#[test]
fn fallback_error_line_re_compiles() {
    assert!(Regex::new(r"(?mi)^.+\(\d+,\d+\):\s*error(?:\s+[A-Za-z]{2,}\d{3,})?(?:\s*:.*)?$").is_ok());
}

Prevention

When it happens

Trigger: First use of the dotnet binlog filter triggers static init; the panic occurs only if the embedded regex literal is invalid, which cannot happen with the released pattern. Effectively an internal-invariant assertion at module init.

Common situations: Custom forks/patches editing the regex and introducing invalid syntax (unbalanced parens, bad escapes); regressions from automated refactors touching the string literal.

Related errors


AI-assisted analysis of rtk-ai/rtk@0924356b4c (2026-09-19). Data as JSON: /api/errors/1dc76350b11c84f4. Report an issue: GitHub.

Appendix: source

Thrown at src/cmds/dotnet/binlog.rs:74

    Regex::new(
        r"(?m)^\s*(?P<file>[^\r\n:(]+)\((?P<line>\d+),(?P<column>\d+)\):\s*(?P<kind>error|warning)\s*(?:(?P<code>[A-Za-z]+\d+)\s*:\s*)?(?P<msg>.*)$"
    )
    .expect("valid regex")
});
static BUILD_SUMMARY_RE: LazyLock<Regex> = LazyLock::new(|| {
    Regex::new(r"(?mi)^\s*(?P<count>\d+)\s+(?P<kind>warning|error)\(s\)").expect("valid regex")
});
static ERROR_COUNT_RE: LazyLock<Regex> =
    LazyLock::new(|| Regex::new(r"(?i)\b(?P<count>\d+)\s+error\(s\)").expect("valid regex"));
static WARNING_COUNT_RE: LazyLock<Regex> =
    LazyLock::new(|| Regex::new(r"(?i)\b(?P<count>\d+)\s+warning\(s\)").expect("valid regex"));
static FALLBACK_ERROR_LINE_RE: LazyLock<Regex> = LazyLock::new(|| {
    Regex::new(r"(?mi)^.+\(\d+,\d+\):\s*error(?:\s+[A-Za-z]{2,}\d{3,})?(?:\s*:.*)?$")
        .expect("valid regex")
});
static FALLBACK_WARNING_LINE_RE: LazyLock<Regex> = LazyLock::new(|| {
    Regex::new(r"(?mi)^.+\(\d+,\d+\):\s*warning(?:\s+[A-Za-z]{2,}\d{3,})?(?:\s*:.*)?$")
        .expect("valid regex")
});
static DURATION_RE: LazyLock<Regex> = LazyLock::new(|| {
    Regex::new(r"(?m)^\s*Time Elapsed\s+(?P<duration>[^\r\n]+)$").expect("valid regex")
});
static TEST_RESULT_RE: LazyLock<Regex> = LazyLock::new(|| {
    Regex::new(
        r"(?m)(?:Passed!|Failed!)\s*-\s*Failed:\s*(?P<failed>\d+),\s*Passed:\s*(?P<passed>\d+),\s*Skipped:\s*(?P<skipped>\d+),\s*Total:\s*(?P<total>\d+),\s*Duration:\s*(?P<duration>[^\r\n-]+)"
    )
    .expect("valid regex")
});
static TEST_SUMMARY_RE: LazyLock<Regex> = LazyLock::new(|| {
    Regex::new(
        r"(?mi)^\s*Test summary:\s*total:\s*(?P<total>\d+),\s*failed:\s*(?P<failed>\d+),\s*(?:succeeded|passed):\s*(?P<passed>\d+),\s*skipped:\s*(?P<skipped>\d+),\s*duration:\s*(?P<duration>[^\r\n]+)$"
    )
    .expect("valid regex")
});
static FAILED_TEST_HEAD_RE: LazyLock<Regex> = LazyLock::new(|| {
    Regex::new(r"(?m)^\s*Failed\s+(?P<name>[^\r\n\[]+)\s+\[[^\]\r\n]+\]\s*$").expect("valid regex")

View on GitHub (pinned to 0924356b4c)