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

get_common_options: Failed to deserialize…

Error message

get_common_options: Failed to deserialize InternalDbtNodeWrapper: {e}

What it means

Raised by get_common_options() when the `node` argument fails to deserialize into InternalDbtNodeWrapper. The macro needs node metadata (relation info, config, resource type) to compute common options, so a non-conforming node value aborts with this SerdeDeserializeError and the serde reason appended.

Solutions

  1. Inspect the appended serde error for the missing or mistyped node field.
  2. Pass the real node object (e.g. `model` in a materialization) as the second argument.
  3. If building nodes programmatically, serialize a full InternalDbtNodeWrapper rather than a partial dict.
  4. Update templates and adapter together to avoid schema drift.

Example fix

// before
{% set opts = adapter.get_common_options(config.model, none) %}

// after
{% set opts = adapter.get_common_options(config.model, model) %}
Defensive patterns

Strategy: validation

Validate before calling

{% if model is mapping and model.get('unique_id') is defined %}
  {% set opts = adapter.get_common_options(config.model, model) %}
{% endif %}

Type guard

fn is_node(val: &minijinja::Value) -> bool {
    minijinja_value_to_typed_struct::<InternalDbtNodeWrapper>(val.clone()).is_ok()
}

Prevention

When it happens

Trigger: adapter.get_common_options(config, node, temporary=...) invoked with node = None, a scalar, a relation object, or a dict missing required InternalDbtNodeWrapper fields (e.g. after schema changes or hand-crafted test nodes).

Common situations: Custom incremental/table materializations passing the wrong context variable for node; partial node dicts in tests; version mismatch between templates and adapter crate.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — 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/0c7391f4db3a5816. Report an issue: GitHub.

Appendix: source

Thrown at crates/dbt-adapter/src/adapter/mod.rs:2195

                let config_val = iter.next_arg::<&Value>()?;
                let node_val = iter.next_arg::<&Value>()?;
                let temporary = iter
                    .next_kwarg::<Option<bool>>("temporary")?
                    .unwrap_or(false);
                iter.finish()?;

                let config = minijinja_value_to_typed_struct::<ModelConfig>(config_val.clone())
                    .map_err(|e| {
                        minijinja::Error::new(
                            minijinja::ErrorKind::SerdeDeserializeError,
                            format!("get_common_options: Failed to deserialize config: {e}"),
                        )
                    })?;
                let node = minijinja_value_to_typed_struct::<InternalDbtNodeWrapper>(
                    node_val.clone(),
                )
                .map_err(|e| {
                    minijinja::Error::new(
                        minijinja::ErrorKind::SerdeDeserializeError,
                        format!(
                            "get_common_options: Failed to deserialize InternalDbtNodeWrapper: {e}"
                        ),
                    )
                })?;

                let options = adapter.get_common_options(state, config, &node, temporary)?;
                Ok(options)
            }
            Parse(_) => Ok(none_value()),
        }
    }

    /// Add time ingestion partition column
    ///
    /// https://github.com/dbt-labs/dbt-adapters/blob/main/dbt-bigquery/src/dbt/adapters/bigquery/impl.py#L259
    ///

View on GitHub (pinned to 0267ce9170)