{"record":{"id":"a24b049c792090bd","repo":"Hmbown/CodeWhale","slug":"tag-regex-pattern-is-valid","errorCode":null,"errorMessage":"tag regex pattern is valid","messagePattern":"tag regex pattern is valid","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/web/scrape.rs","lineNumber":48,"sourceCode":"\nfn get_title_re() -> &'static Regex {\n    TITLE_RE.get_or_init(|| {\n        Regex::new(r#\"<a[^>]*class=\\\"result__a\\\"[^>]*href=\\\"([^\\\"]+)\\\"[^>]*>(.*?)</a>\"#)\n            .expect(\"title regex pattern is valid\")\n    })\n}\n\nfn get_snippet_re() -> &'static Regex {\n    SNIPPET_RE.get_or_init(|| {\n        Regex::new(\n            r#\"<a[^>]*class=\\\"result__snippet\\\"[^>]*>(.*?)</a>|<div[^>]*class=\\\"result__snippet\\\"[^>]*>(.*?)</div>\"#,\n        )\n        .expect(\"snippet regex pattern is valid\")\n    })\n}\n\nfn get_tag_re() -> &'static Regex {\n    TAG_RE.get_or_init(|| Regex::new(r\"<[^>]+>\").expect(\"tag regex pattern is valid\"))\n}\n\nfn get_bing_result_re() -> &'static Regex {\n    BING_RESULT_RE.get_or_init(|| {\n        Regex::new(r#\"(?is)<li[^>]*class=\\\"[^\\\"]*\\bb_algo\\b[^\\\"]*\\\"[^>]*>(.*?)</li>\"#)\n            .expect(\"bing result regex pattern is valid\")\n    })\n}\n\nfn get_bing_title_re() -> &'static Regex {\n    BING_TITLE_RE.get_or_init(|| {\n        Regex::new(r#\"(?is)<h2[^>]*>.*?<a[^>]*href=\\\"([^\\\"]+)\\\"[^>]*>(.*?)</a>\"#)\n            .expect(\"bing title regex pattern is valid\")\n    })\n}\n\nfn get_bing_snippet_re() -> &'static Regex {\n    BING_SNIPPET_RE.get_or_init(|| {","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/tools/web/scrape.rs#L30-L66","documentation":"Panic compiling the generic HTML tag-stripping pattern `<[^>]+>` in `TAG_RE.get_or_init`. This is the simplest of the scrape literals; the expect can only fire if the literal was edited into something the regex crate rejects (a stray `*`/`+` with nothing to repeat, or an unbalanced bracket class).","triggerScenarios":"An edit to the tag-stripping literal that breaks regex syntax; the first text normalization over scraped HTML after that build panics inside `get_tag_re`.","commonSituations":"Trying to also strip self-closing or malformed tags (e.g. adding `/?` incorrectly or a broken character class) without re-running tests.","solutions":["Restore or fix the literal — the regex crate's error message in the panic payload names the exact offset.","Cover the getter in the shared pattern-compile unit test.","Re-run the scrape tests after the edit."],"exampleFix":"// before\nRegex::new(r\"<[^>]+>\").expect(\"tag regex pattern is valid\")\n\n// after: assert the edited variant still strips a sample tag\n#[test]\nfn tag_stripper_still_works() {\n    assert_eq!(get_tag_re().replace_all(\"a<b>c</b>d\", \"\"), \"acd\");\n}","handlingStrategy":"validation","validationCode":"#[test]\nfn tag_pattern_still_strips() {\n    assert_eq!(get_tag_re().replace_all(\"a<b>c</b>d\", \"\"), \"acd\");\n}","typeGuard":null,"tryCatchPattern":"let text = std::panic::catch_unwind(|| strip_tags(&html))\n    .unwrap_or_else(|_| html.to_string());","preventionTips":["Keep the tag-stripping literal minimal; add tests for any widened variant.","Include the getter in the shared pattern-compile test."],"tags":["rust","regex","html-sanitization","panic","expect"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}