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
- Ensure columns is a dict keyed by column name, each value a valid column definition (e.g. {"id": {"name": "id", "data_type": "int"}})
- Add all fields required by DbtColumn to each entry
- Use adapter.get_columns_in_relation() output rather than hand-built dicts when possible
- 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
- Use adapter.get_columns_in_relation() to source column dicts instead of hand-building them
- Keep each column dict complete with all DbtColumn-required fields
- Log the columns value with log() to verify shape before calling
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
- 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}
- compute_external_path: Failed to deserialize InternalDbtNode
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/c177f904260a3110.
Report an issue: GitHub.