{"record":{"id":"4a4fcd7e87683210","repo":"dbt-labs/dbt-core","slug":"valid-regex-4a4fcd","errorCode":null,"errorMessage":"valid regex","messagePattern":"valid regex","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"info","filePath":"crates/dbt-adapter/src/time_machine/event_replay.rs","lineNumber":33,"sourceCode":"use flate2::read::GzDecoder;\nuse parking_lot::RwLock;\nuse regex::Regex;\nuse serde::{Deserialize, Serialize};\nuse similar::{ChangeTag, TextDiff};\n\nuse super::event::{\n    AdapterCallEvent, CacheInvalidationEvent, MetadataCallArgs, MetadataCallEvent, RecordedEvent,\n    RecordingHeader, RunCacheCloneEvent, RunRemoteAdhocEvent, SaoEvent,\n};\nuse super::semantic::SemanticCategory;\nuse super::serde::values_match;\nuse super::validation::{SqlSanitizer, TmpSuffixSanitizer, UuidSanitizer};\nuse crate::AdapterType;\nuse crate::sql::diff::{canonicalize_python_model_pair, compare_sql};\n\n/// Marker for temp-relation identifiers, which carry a non-deterministic suffix.\nstatic TMP_MARKER_RE: LazyLock<Regex> =\n    LazyLock::new(|| Regex::new(r\"(?i)__dbt_tmp\").expect(\"valid regex\"));\n\n/// Extract the SQL string from args (first string in array, or the string itself).\n///\n/// For execute/run_query, args are serialized as `[sql, auto_begin, fetch, limit, options]`\n/// so SQL is the first element of the array.\nfn extract_sql_from_args(args: &serde_json::Value) -> Option<&str> {\n    match args {\n        serde_json::Value::String(s) => Some(s.as_str()),\n        serde_json::Value::Array(arr) => arr.first().and_then(|v| v.as_str()),\n        _ => None,\n    }\n}\n\nfn is_sql_method(method: &str) -> bool {\n    method == \"execute\" || method == \"run_query\"\n}\n\n/// Returns true if the SQL string is read-only and cannot mutate DB state.","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-adapter/src/time_machine/event_replay.rs#L15-L51","documentation":"A `Regex::new(r\"(?i)__dbt_tmp\").expect(\"valid regex\")` inside a `LazyLock` used to mark temp-relation identifiers carrying non-deterministic `__dbt_tmp` suffixes. `expect` here only fires if the regex fails to COMPILE. Because the pattern is a compile-time constant and is known-valid, this panic is unreachable in any build containing this exact source.","triggerScenarios":"Not triggerable by callers at all. Would only panic if the source constant were edited to an invalid regex (e.g. an unbalanced group) — then the first use of TMP_MARKER_RE in event_replay panics at LazyLock initialization time, on the first call to any function referencing it.","commonSituations":"Only during development: editing the pattern and introducing a regex syntax error; symptoms show up as a first-use panic rather than a compile error, often confusing developers who expect static checking.","solutions":["Check the pattern literal in crates/dbt-adapter/src/time_machine/event_replay.rs for regex syntax errors (unescaped brackets, unbalanced parens) and fix it.","Test the pattern in a regex debugger (e.g. regex101 with the Rust `regex` crate flavor) before committing changes.","Optionally add a #[test] that constructs TMP_MARKER_RE so a bad pattern fails in CI with a clear test name.","Consider `once_cell`-style compile-time validation via build.rs or the `lazy_static` + test approach to fail earlier."],"exampleFix":"// before (typo introduced during edit)\nRegex::new(r\"(?i)__dbt_tmp\").expect(\"valid regex\")  // OK, but suppose r\"(?i)__dbt_tmp(\" was committed\n// after\nRegex::new(r\"(?i)__dbt_tmp\").expect(\"TMP_MARKER_RE must be a valid regex\")\n// plus a guard test:\n#[test]\nfn tmp_marker_regex_compiles() { LazyLock::force(&TMP_MARKER_RE); }","handlingStrategy":"validation","validationCode":"// CI-time check that all LazyLock regexes compile:\n#[test]\nfn marker_regexes_compile() {\n    LazyLock::force(&TMP_MARKER_RE);\n    assert!(TMP_MARKER_RE.is_match(\"my_model__dbt_tmp\"));\n}","typeGuard":"fn valid_static_regex(pattern: &str) -> bool { Regex::new(pattern).is_ok() }","tryCatchPattern":"std::panic::catch_unwind(|| LazyLock::force(&TMP_MARKER_RE))\n    .map_err(|_| anyhow::anyhow!(\"static regex failed to compile — check event_replay.rs pattern\"))?;","preventionTips":["Run pattern changes through a regex syntax checker with the Rust `regex` crate dialect before committing.","Add compile-only unit tests for every LazyLock<Regex> in the codebase.","Remember these panics surface at first use, not at compile time — keep the pattern simple and well-escaped."],"tags":["rust","regex","panic","static-initialization"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}