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

get_view_options: Failed to deserialize InternalDbtNodeWrapp

Error message

get_view_options: Failed to deserialize InternalDbtNodeWrapper: {e}

What it means

Same failure mode as the get_table_options node error but raised from get_view_options(): the `node` argument cannot be converted from a minijinja Value into InternalDbtNodeWrapper. The library raises this because the view-options logic needs structured node metadata (schema, database, aliases) and the supplied value is not a valid node object.

Source

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

        match &self.inner {
            Typed { adapter, .. } => {
                let iter = ArgsIter::new("get_view_options", &["config", "node"], args);
                let config_val = iter.next_arg::<&Value>()?;
                let node_val = iter.next_arg::<&Value>()?;
                iter.finish()?;

                let config = minijinja_value_to_typed_struct::<ModelConfig>(config_val.clone())
                    .map_err(|e| {
                        minijinja::Error::new(
                            minijinja::ErrorKind::SerdeDeserializeError,
                            format!("get_view_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_view_options: Failed to deserialize InternalDbtNodeWrapper: {e}"
                        ),
                    )
                })?;

                let inner_node = node.as_internal_node();
                let options = adapter.get_view_options(state, config, inner_node.common())?;
                Ok(Value::from_serialize(options))
            }
            Parse(_) => Ok(none_value()),
        }
    }

    #[tracing::instrument(skip(self, state), level = "trace")]
    pub fn get_common_options(
        &self,

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Check the appended serde message for the exact missing/mistyped node field.
  2. Pass the model node object from the materialization context (e.g. `model`) as the second argument.
  3. Ensure the node dict contains all fields required by InternalDbtNodeWrapper (common metadata, config, etc.).
  4. Keep macro templates and the adapter crate on matching versions to avoid schema drift.

Example fix

// before
{% do adapter.get_view_options(config.model, this) %}

// after
{% do adapter.get_view_options(config.model, model) %}
Defensive patterns

Strategy: validation

Validate before calling

{% if model is mapping and model.get('unique_id') is defined %}
  {% do adapter.get_view_options(config.model, model) %}
{% else %}
  {{ exceptions.raise_compiler_error("get_view_options requires a valid node object") }}
{% 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_view_options(config, node) invoked with a node that is missing required wrapper fields, is None/undefined, is a scalar, or was constructed from a different node schema version.

Common situations: Custom view materializations passing `this` or a relation instead of the node dict; macros refactored to pass different context variables; tests building partial node dicts.

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