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

get_common_options: Failed to deserialize config: {e}

Error message

get_common_options: Failed to deserialize config: {e}

What it means

get_common_options() converts its `config` argument into a ModelConfig struct via serde before computing shared DDL options. When the supplied config Value cannot be deserialized into ModelConfig, this SerdeDeserializeError is raised with the serde detail appended. It signals the config object passed from Jinja does not match the ModelConfig schema.

Source

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

    #[tracing::instrument(skip(self, state), level = "trace")]
    pub fn get_common_options(
        &self,
        state: &State,
        args: &[Value],
    ) -> Result<Value, minijinja::Error> {
        match &self.inner {
            Typed { adapter, .. } => {
                let iter = ArgsIter::new("get_common_options", &["config", "node"], args);
                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)

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Read the serde detail appended to the message to find the failing field.
  2. Pass config.model from the materialization context instead of a hand-built dict.
  3. Fix the offending value's type in the model config block or dbt_project.yml.
  4. Reconcile custom macros with this adapter version's ModelConfig field names and types.

Example fix

// before
{% do adapter.get_common_options({'temporary': 'true'}, model) %}

// after
{% do adapter.get_common_options(config.model, model, temporary=true) %}
Defensive patterns

Strategy: validation

Validate before calling

{% if config.model is mapping %}
  {% set opts = adapter.get_common_options(config.model, model, temporary=Temporary) %}
{% endif %}

Prevention

When it happens

Trigger: adapter.get_common_options(config, node, temporary=...) called with a config dict containing fields of wrong types (e.g. non-bool where bool expected, non-list tags), unknown incompatible values, or a non-object config.

Common situations: Custom materializations (table/view/incremental) passing raw dicts instead of config.model; config keys renamed between dbt versions; user YAML values that fail strict typed parsing (e.g. a quoted boolean string).

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/c83ebb3571f02b46. Report an issue: GitHub.