dbt-labs/dbt-core · error

{}

Error message

{}

What it means

This error wraps a serde deserialization failure (kind SerdeDeserializeError) that occurred while converting the Jinja `columns` argument of `update_columns` into an IndexMap<String, DbtColumn>. The library throws it because the columns value passed from Jinja does not match the expected structure: a mapping of column name -> column definition with DbtColumn's required fields.

Source

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

                Ok(result)
            }
            Parse(_) => Ok(none_value()),
        }
    }

    #[tracing::instrument(skip(self, state), level = "trace")]
    pub fn update_columns(&self, state: &State, args: &[Value]) -> Result<Value, minijinja::Error> {
        match &self.inner {
            Typed { adapter, .. } => {
                let iter = ArgsIter::new("update_columns", &["relation", "columns"], args);
                let relation_val = iter.next_arg::<&Value>()?;
                let relation = downcast_value_to_dyn_base_relation(relation_val)?;
                let columns_val = iter.next_arg::<&Value>()?;
                let columns = minijinja_value_to_typed_struct::<IndexMap<String, DbtColumn>>(
                    columns_val.clone(),
                )
                .map_err(|e| {
                    minijinja::Error::new(
                        minijinja::ErrorKind::SerdeDeserializeError,
                        e.to_string(),
                    )
                })?;
                iter.finish()?;

                let mut conn =
                    adapter.borrow_tlocal_connection(Some(state), node_id_from_state(state))?;
                let result = adapter.update_columns_descriptions(
                    state,
                    conn.as_mut(),
                    &relation,
                    columns,
                    self.cancellation_token.clone(),
                )?;
                Ok(result)
            }
            Parse(_) => Ok(none_value()),

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Ensure columns is a dict keyed by column name, each value a valid column definition (e.g. {"id": {"name": "id", "data_type": "int"}})
  2. Add all fields required by DbtColumn to each entry
  3. Use adapter.get_columns_in_relation() output rather than hand-built dicts when possible
  4. Read the wrapped serde message (rendered in place of {}) to identify the exact missing/mistyped field

Example fix

// before (Jinja)
{{ update_columns(relation, ['id', 'name']) }}
// after
{% set cols = {'id': {'name': 'id', 'data_type': 'int'}} %}
{{ update_columns(relation, cols) }}
Defensive patterns

Strategy: validation

Validate before calling

{% if columns is not mapping %}
  {{ exceptions.raise_compiler_error("update_columns requires a dict of column definitions") }}
{% endif %}

Try / catch

{% set cols = columns if columns is mapping else {} %}
{{ update_columns(relation, cols) }}

Prevention

When it happens

Trigger: Calling `update_columns(relation, columns)` where `columns` is not a plain name->column map: missing required DbtColumn fields, wrong field types (e.g. string where a list is expected), passing a list of columns instead of a dict, or passing nested/extra values that fail strict deserialization.

Common situations: Building the columns dict by hand in Jinja and missing a required column attribute like name or data_type; passing columns from a schema.yml parse result in the wrong shape; version drift where DbtColumn gained or renamed a required field.

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