dbt-labs/dbt-core · error
compute_external_path: Failed to deserialize InternalDbtNode
Error message
compute_external_path: Failed to deserialize InternalDbtNodeWrapper: {e} What it means
Raised in `compute_external_path` when the `model` argument cannot be deserialized into an InternalDbtNodeWrapper struct. The prefixed message distinguishes node-deserialization failure from config failure in the same function. It means the value passed as the model node does not match the internal node schema.
Source
Thrown at crates/dbt-adapter/src/adapter/mod.rs:2830
let model_val = iter.next_arg::<&Value>()?;
let is_incremental = iter
.next_kwarg::<Option<bool>>("is_incremental")?
.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!("compute_external_path: Failed to deserialize config: {e}"),
)
})?;
let node = minijinja_value_to_typed_struct::<InternalDbtNodeWrapper>(
model_val.clone(),
)
.map_err(|e| {
minijinja::Error::new(
minijinja::ErrorKind::SerdeDeserializeError,
format!(
"compute_external_path: Failed to deserialize InternalDbtNodeWrapper: {e}"
),
)
})?;
let result = adapter.compute_external_path(
config,
node.as_internal_node(),
is_incremental,
)?;
Ok(Value::from(result))
}
Parse(_) => Ok(empty_string_value()),
}
}
View on GitHub (pinned to 0267ce9170)
Solutions
- Pass the actual model node object (e.g. from the model context) rather than a name, relation, or partial dict
- Check the wrapped serde message for the missing or mistyped node field
- If constructing a node, include all fields InternalDbtNodeWrapper requires
- Upgrade/align custom code with the node schema of the installed dbt version
Example fix
// before (Jinja)
{{ compute_external_path(config, model_name, ...) }}
// after
{{ compute_external_path(config, model, ...) }} Defensive patterns
Strategy: type-guard
Validate before calling
{% if model is not mapping or 'unique_id' not in model %}
{{ exceptions.raise_compiler_error("compute_external_path requires a full model node") }}
{% endif %} Type guard
{% macro is_model_node(v) %}
{{ return(v is mapping and 'unique_id' in v and 'resource_type' in v) }}
{% endmacro %} Try / catch
{% if model is not mapping or 'unique_id' not in model %}
{% set model = model.config.model if model is mapping else none %}
{% endif %} Prevention
- Pass the actual model node object, never a name or relation
- Do not trim node dicts before passing to adapter functions
- Re-validate node construction after dbt upgrades
When it happens
Trigger: Calling `compute_external_path` with a model value that is not a full dbt node (e.g. a relation, a string model name, or a trimmed dict), or a node dict missing fields required by InternalDbtNodeWrapper such as unique_id, resource_type, or path components.
Common situations: Passing `this` (a relation) instead of the model node; passing just the model name; constructing a minimal node dict in a test macro; internal node schema changes across dbt versions breaking hand-assembled nodes.
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_view_options: Failed to deserialize InternalDbtNodeWrapp
- get_common_options: Failed to deserialize InternalDbtNodeWra
- {}
- compute_external_path: Failed to deserialize config: {e}
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/3f56b25291434c14.
Report an issue: GitHub.