dbt-labs/dbt-core · info
valid regex
Error message
valid regex
What it means
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.
Source
Thrown at crates/dbt-adapter/src/time_machine/event_replay.rs:33
use flate2::read::GzDecoder;
use parking_lot::RwLock;
use regex::Regex;
use serde::{Deserialize, Serialize};
use similar::{ChangeTag, TextDiff};
use super::event::{
AdapterCallEvent, CacheInvalidationEvent, MetadataCallArgs, MetadataCallEvent, RecordedEvent,
RecordingHeader, RunCacheCloneEvent, RunRemoteAdhocEvent, SaoEvent,
};
use super::semantic::SemanticCategory;
use super::serde::values_match;
use super::validation::{SqlSanitizer, TmpSuffixSanitizer, UuidSanitizer};
use crate::AdapterType;
use crate::sql::diff::{canonicalize_python_model_pair, compare_sql};
/// Marker for temp-relation identifiers, which carry a non-deterministic suffix.
static TMP_MARKER_RE: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"(?i)__dbt_tmp").expect("valid regex"));
/// Extract the SQL string from args (first string in array, or the string itself).
///
/// For execute/run_query, args are serialized as `[sql, auto_begin, fetch, limit, options]`
/// so SQL is the first element of the array.
fn extract_sql_from_args(args: &serde_json::Value) -> Option<&str> {
match args {
serde_json::Value::String(s) => Some(s.as_str()),
serde_json::Value::Array(arr) => arr.first().and_then(|v| v.as_str()),
_ => None,
}
}
fn is_sql_method(method: &str) -> bool {
method == "execute" || method == "run_query"
}
/// Returns true if the SQL string is read-only and cannot mutate DB state.View on GitHub (pinned to 0267ce9170)
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.
Example fix
// before (typo introduced during edit)
Regex::new(r"(?i)__dbt_tmp").expect("valid regex") // OK, but suppose r"(?i)__dbt_tmp(" was committed
// after
Regex::new(r"(?i)__dbt_tmp").expect("TMP_MARKER_RE must be a valid regex")
// plus a guard test:
#[test]
fn tmp_marker_regex_compiles() { LazyLock::force(&TMP_MARKER_RE); } Defensive patterns
Strategy: validation
Validate before calling
// CI-time check that all LazyLock regexes compile:
#[test]
fn marker_regexes_compile() {
LazyLock::force(&TMP_MARKER_RE);
assert!(TMP_MARKER_RE.is_match("my_model__dbt_tmp"));
} Type guard
fn valid_static_regex(pattern: &str) -> bool { Regex::new(pattern).is_ok() } Try / catch
std::panic::catch_unwind(|| LazyLock::force(&TMP_MARKER_RE))
.map_err(|_| anyhow::anyhow!("static regex failed to compile — check event_replay.rs pattern"))?; Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- valid regex
- [^0-9a-zA-Z_]+
- [/\\]
- Schema not found for canonical FQN: {}
- `EnterGuard` values dropped out of order. Guards returned by
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/4a4fcd7e87683210.
Report an issue: GitHub.