dbt-labs/dbt-core · error

compute_external_path: Failed to deserialize…

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.

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.

Appendix: 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)