dbt-labs/dbt-core · error · minijinja::Error

target is not set in state

Error message

target is not set in state

What it means

get_relations_by_pattern derives a default database from the render state's `target` when no database argument is supplied. If `state.lookup("target")` returns None — target not injected into state — this InvalidOperation error is raised. It indicates the adapter runtime was invoked without an initialized target context.

Solutions

  1. Pass the database argument explicitly so state lookup is not needed.
  2. Ensure the runtime injects `target` into the state before executing macros.
  3. Fix test/embedded harnesses to populate state with a target containing a `database` attribute.
  4. Catch the error and default to the configured target's database from your own config if acceptable.

Example fix

// before
let rels = get_relations_by_pattern(pattern, None, excluded)?;

// after
let rels = get_relations_by_pattern(pattern, Some("analytics_db".into()), excluded)?;
Defensive patterns

Strategy: try-catch

Validate before calling

{% set has_target = state is defined and state.get('target', none) is not none %}

Type guard

fn state_has_target(state: &Value) -> bool {
    state.lookup("target", &[]).is_some()
}

Try / catch

{% try %}
  {% set rels = get_relations_by_pattern(pattern, none, excluded) %}
{% except %}
  {% set rels = get_relations_by_pattern(pattern, target.database, excluded) %}
{% endtry %}

Prevention

When it happens

Trigger: Calling get_relations_by_pattern without a database argument while the minijinja state has no `target` object — e.g. invoking the function outside a normal dbt run context, in tests, or in tooling that builds the Jinja env manually.

Common situations: Unit-testing macros with a hand-rolled state missing target; custom scripts calling adapter methods before target resolution; partial state setup in embedded usage of the adapter runtime.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at crates/dbt-adapter/src/adapter/adapter_impl.rs:1705

        excluded_schemas: Option<Value>,
    ) -> Result<Value, minijinja::Error> {
        // Validate excluded_schemas if provided
        if let Some(ref schemas) = excluded_schemas {
            let _ =
                minijinja_value_to_typed_struct::<Vec<String>>(schemas.clone()).map_err(|e| {
                    minijinja::Error::new(
                        minijinja::ErrorKind::SerdeDeserializeError,
                        e.to_string(),
                    )
                })?;
        }

        // Get default database from state if not provided
        let database_str = if let Some(db) = database {
            db.to_string()
        } else {
            let target = state.lookup("target", &[]).ok_or_else(|| {
                minijinja::Error::new(
                    minijinja::ErrorKind::InvalidOperation,
                    "target is not set in state",
                )
            })?;
            let db_value = target.get_attr("database").unwrap_or_default();
            db_value.as_str().unwrap_or_default().to_string()
        };

        // Build args array for macro call
        // Note: For optional string parameters like 'exclude', we pass empty string instead of None
        // because the macro expects a string and None gets converted to "none" string
        let args = vec![
            Value::from(schema_pattern),
            Value::from(table_pattern),
            exclude.map(Value::from).unwrap_or_else(|| Value::from("")),
            Value::from(database_str.as_str()),
            quote_table
                .map(Value::from)

View on GitHub (pinned to 0267ce9170)