Hmbown/CodeWhale · error
title regex pattern is valid
Error message
title regex pattern is valid
What it means
Panic compiling the DuckDuckGo title pattern (`<a[^>]*class="result__a"[^>]*href="([^"]+)"...`) on first use via `TITLE_RE.get_or_init`. The `regex` crate returns `Err` for syntactically invalid patterns; because the pattern is a hardcoded literal verified the first time it runs, this expect fires only after someone edits the literal into an invalid regex (unbalanced group, bad escape, stray quantifier). On panic the `OnceLock` stays uninitialized, so the next call retries initialization.
Source
Thrown at crates/tui/src/tools/web/scrape.rs:34
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ScrapedSearchResult {
pub title: String,
pub url: String,
pub snippet: Option<String>,
}
// Cached regex patterns for HTML parsing
static TITLE_RE: OnceLock<Regex> = OnceLock::new();
static SNIPPET_RE: OnceLock<Regex> = OnceLock::new();
static TAG_RE: OnceLock<Regex> = OnceLock::new();
static BING_RESULT_RE: OnceLock<Regex> = OnceLock::new();
static BING_TITLE_RE: OnceLock<Regex> = OnceLock::new();
static BING_SNIPPET_RE: OnceLock<Regex> = OnceLock::new();
fn get_title_re() -> &'static Regex {
TITLE_RE.get_or_init(|| {
Regex::new(r#"<a[^>]*class=\"result__a\"[^>]*href=\"([^\"]+)\"[^>]*>(.*?)</a>"#)
.expect("title regex pattern is valid")
})
}
fn get_snippet_re() -> &'static Regex {
SNIPPET_RE.get_or_init(|| {
Regex::new(
r#"<a[^>]*class=\"result__snippet\"[^>]*>(.*?)</a>|<div[^>]*class=\"result__snippet\"[^>]*>(.*?)</div>"#,
)
.expect("snippet regex pattern is valid")
})
}
fn get_tag_re() -> &'static Regex {
TAG_RE.get_or_init(|| Regex::new(r"<[^>]+>").expect("tag regex pattern is valid"))
}
fn get_bing_result_re() -> &'static Regex {
BING_RESULT_RE.get_or_init(|| {View on GitHub (pinned to 0c42157ee5)
Solutions
- Fix the pattern syntax: validate it with the Rust regex flavor (a scratch `Regex::new(pat)` test or an online tester set to Rust).
- Add/keep a unit test that forces initialization of all six getters so edits fail in CI, not at scrape time.
- Run `scripts/dev-test.sh crates/tui/src/tools/web/scrape.rs` (or `cargo test -p codewhale-tui --lib scrape`) after touching the pattern.
Example fix
// before
Regex::new(r#"<a[^>]*class=\"result__a\"[^>]*href=\"([^\"]+)\"[^>]*>(.*?)</a>"#)
.expect("title regex pattern is valid")
// after: pin every literal with a compile test so edits fail in CI
#[test]
fn scrape_patterns_compile() {
let _ = get_title_re();
let _ = get_snippet_re();
let _ = get_tag_re();
let _ = get_bing_result_re();
let _ = get_bing_title_re();
let _ = get_bing_snippet_re();
} Defensive patterns
Strategy: validation
Validate before calling
// Force-compile all scrape patterns before relying on them in a session
#[test]
fn scrape_patterns_compile() {
let _ = get_title_re();
let _ = get_snippet_re();
let _ = get_tag_re();
let _ = get_bing_result_re();
let _ = get_bing_title_re();
let _ = get_bing_snippet_re();
} Try / catch
let results = std::panic::catch_unwind(|| parse_duckduckgo_results(&html, max_results))
.unwrap_or_default(); Prevention
- Validate edited patterns against the Rust regex flavor — no backreferences, no lookaround.
- Run the scrape tests after every pattern edit.
- Keep SERP patterns as untouched literals in release branches.
When it happens
Trigger: A code change to the literal that breaks regex syntax; the first `parse_duckduckgo_results` call after that build panics inside `get_or_init` while scraping or testing.
Common situations: Adjusting the DDG HTML selector without running the scrape tests; copy-pasting a PCRE/JavaScript construct the regex crate rejects (backreferences, lookaround) into the literal.
Related errors
- snippet regex pattern is valid
- bing result regex pattern is valid
- bing title regex pattern is valid
- bing snippet regex pattern is valid
- tag regex pattern is valid
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/98a174f43b278105.
Report an issue: GitHub.