dbt-labs/dbt-core · error · minijinja::Error (InvalidOperation)

FailFast Error

Error message

FailFast Error: {message}

What it means

Fallback variant of the fail-fast error: `exceptions.raise_fail_fast_error(msg=...)` was invoked but no node id/file path could be recovered from the Jinja state, so only 'FailFast Error: {message}' is reported. The run still halts as the macro author intended.

Solutions

  1. Fix the condition described in the message — the run abort is intentional.
  2. Run through `dbt run`/`build` to get the located variant showing the raising node/file.
  3. Adjust the macro to only raise within node contexts if the parse-time firing is unintended.

Example fix

# before
# FailFast Error: row count is 0

# after
$ dbt build --select my_model
# FailFast Error for model.my_model from models/my_model.sql: row count is 0
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure fail-fast guards execute within a node context for locatable errors
if state.lookup("node_id").is_none() {
    // skip or defer the guard to the run phase
}

Try / catch

match result {
    Err(e) if e.message.contains("FailFast Error") => {
        // deliberate abort; handle msg and stop the pipeline
    }
    other => other,
}

Prevention

When it happens

Trigger: Explicit `raise_fail_fast_error(msg=...)` call during Jinja evaluation where `node_metadata_from_state(state)` returns None (evaluation outside a node context, parse-time execution, or dispatched macro without node metadata).

Common situations: Fail-fast guards in macros that run during parse/compile or in contexts without node attribution; the same guard fires fine under `dbt run` but without file info elsewhere.

Related errors


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/0af792ceea94dffc. Report an issue: GitHub.

Appendix: source

Thrown at crates/dbt-jinja-utils/src/functions/base.rs:1289

                    ))
                }
            }
            // (msg, node=None)
            "raise_fail_fast_error" => {
                let mut args = ArgParser::new(args, None);
                let message = args.get::<String>("msg")?;
                if let Some((node_id, file_path)) = node_metadata_from_state(state) {
                    Err(Error::new(
                        ErrorKind::InvalidOperation,
                        format!(
                            "FailFast Error for {} from {}: {}",
                            node_id,
                            file_path.display(),
                            message
                        ),
                    ))
                } else {
                    Err(Error::new(
                        ErrorKind::InvalidOperation,
                        format!("FailFast Error: {message}"),
                    ))
                }
            }
            // (snapshot_time_data_type: str, updated_at_data_type: str)
            "warn_snapshot_timestamp_data_types" => {
                let mut args = ArgParser::new(args, None);
                let snapshot_time_data_type = args
                    .get::<String>("snapshot_time_data_type")
                    .unwrap_or_else(|_| "".to_string());
                let updated_at_data_type = args
                    .get::<String>("updated_at_data_type")
                    .unwrap_or_else(|_| "".to_string());

                let metadata = node_metadata_from_state(state);
                let snapshot_name = state.lookup("model", &[]).and_then(|m| {
                    m.get_attr("name")

View on GitHub (pinned to 0267ce9170)