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

  1. Pass the actual model node object (e.g. from the model context) rather than a name, relation, or partial dict
  2. Check the wrapped serde message for the missing or mistyped node field
  3. If constructing a node, include all fields InternalDbtNodeWrapper requires
  4. 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

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


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/3f56b25291434c14. Report an issue: GitHub.