dbt-labs/dbt-core · error

compute_external_path: Failed to deserialize config: {e}

Error message

compute_external_path: Failed to deserialize config: {e}

What it means

Raised in `compute_external_path` when the `config` argument cannot be deserialized into a ModelConfig struct. The library wraps the underlying serde error with this prefixed message so the failing step (config deserialization) is identifiable. It indicates the config object passed from Jinja does not conform to ModelConfig's expected schema.

Source

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

    #[tracing::instrument(skip_all, level = "trace")]
    pub fn compute_external_path(
        &self,
        _state: &State,
        args: &[Value],
    ) -> Result<Value, minijinja::Error> {
        match &self.inner {
            Typed { adapter, .. } => {
                let iter = ArgsIter::new("compute_external_path", &["config", "model"], args);
                let config_val = iter.next_arg::<&Value>()?;
                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(

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Pass the model's actual config object (model.config) rather than a hand-built dict
  2. Check the embedded serde message for the exact missing/mistyped field and fix it
  3. Supply all required ModelConfig fields with correctly typed values
  4. Align custom-materialization code with the ModelConfig schema of your dbt version

Example fix

// before (Jinja)
{{ compute_external_path(config={'external_root': '/tmp'}, model, ...) }}
// after
{{ compute_external_path(config=model.config, model=model, ...) }}
Defensive patterns

Strategy: try-catch

Validate before calling

{% if config is not mapping or 'external_root' not in config %}
  {{ exceptions.raise_compiler_error("compute_external_path requires a valid ModelConfig") }}
{% endif %}

Try / catch

{% set c = config if config is defined else model.config %}
{{ compute_external_path(c, model, ...) }}

Prevention

When it happens

Trigger: Calling `compute_external_path(..., config, model, ...)` with a config Value that lacks required ModelConfig fields, has wrong-typed fields (e.g. non-bool enabled, non-string materialization), or is not a config object at all (e.g. a plain dict from unrelated context).

Common situations: Constructing a fake config dict in a macro instead of using the model's real `config`; partial config objects in custom materializations; ModelConfig schema changed between dbt versions so previously valid configs now miss required fields.

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