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
- Check the appended serde message for the exact missing/mistyped node field.
- Pass the model node object from the materialization context (e.g. `model`) as the second argument.
- Ensure the node dict contains all fields required by InternalDbtNodeWrapper (common metadata, config, etc.).
- 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
- Pass `model` (the node) rather than `this` or a relation
- Avoid partial node dicts in tests — serialize full InternalDbtNodeWrapper objects
- Version-lock templates with adapter changes
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
- get_table_options: Failed to deserialize InternalDbtNodeWrap
- get_common_options: Failed to deserialize InternalDbtNodeWra
- {}
- compute_external_path: Failed to deserialize config: {e}
- compute_external_path: Failed to deserialize InternalDbtNode
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/085473872e87f717.
Report an issue: GitHub.