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

Missing default value for var in dbt_project.yml: {var_name}

Error message

Missing default value for var in dbt_project.yml: {var_name}

What it means

When a `var()` call is evaluated while parsing dbt_project.yml itself (package name resolves to `dbt_project.yml`), the library requires an inline default because there is no yet-parsed var context to fall back on. This error is thrown when `var()` is used without a default value in that phase. It prevents chicken-and-egg resolution of vars during config parsing.

Source

Thrown at crates/dbt-jinja-vars/src/configured_var.rs:94

    }

    fn call_as_function(
        &self,
        state: &State<'_, '_>,
        var_name: String,
        default_value: Option<Value>,
    ) -> Result<Value, Error> {
        // 1. CLI vars
        if let Some(value) = self.cli_vars.get(&var_name) {
            return Ok(cli_var_value_to_minijinja(value));
        }
        // 2. Check if this is dbt_project.yml parsing
        let package_name = self.package_name(state, &var_name)?;
        if package_name == "dbt_project.yml" {
            if let Some(default_value) = default_value {
                return Ok(default_value);
            } else {
                return Err(Error::new(
                    ErrorKind::InvalidOperation,
                    format!("Missing default value for var in dbt_project.yml: {var_name}"),
                ));
            }
        }

        // 3. Package vars
        let vars_lookup = self.vars.get(&package_name).ok_or_else(|| {
            Error::new(
                ErrorKind::InvalidOperation,
                format!("Package vars should be initialized for package: {package_name}"),
            )
        })?;
        if let Some(var) = vars_lookup.get(&var_name) {
            Ok(Value::from_serialize(var))
        } else if let Some(default_value) = default_value {
            Ok(default_value)
        } else if state.lookup("this", &[]).is_none() {

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Provide a default: `var('x', 'default_value')` in dbt_project.yml.
  2. Use `env_var()` for environment-driven configuration instead of `var()` in dbt_project.yml.
  3. Move dynamic values out of dbt_project.yml into model/schema configs where full var resolution is available.

Example fix

# before (dbt_project.yml)
vars:
  lookback: "{{ var('lookback_days') }}"
# after
vars:
  lookback: "{{ var('lookback_days', 7) }}"
Defensive patterns

Strategy: validation

Validate before calling

# lint rule for dbt_project.yml: every var() must have a default
# re: var\(\s*['"][^'"]+['"]\s*\)  (single-arg var calls in project yml are errors)

Prevention

When it happens

Trigger: Using `{{ var('x') }}` (no default) inside dbt_project.yml — e.g. in jinja-templated `vars:` or config blocks — during project file parsing.

Common situations: Templating dbt_project.yml with env-driven vars via `var()` instead of `env_var()`; copying var usage from model SQL into project config; `--vars` flag values not yet available at this parse stage.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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