dbt-labs/dbt-core · error · minijinja::Error::InvalidOperation
existing_columns must be iterable: {e}
Error message
existing_columns must be iterable: {e} What it means
Within parse_columns_and_constraints, the existing_columns argument is iterated via try_iter(); if the Value is not an iterable sequence (e.g. a scalar, dict, or string), the failure is wrapped in an InvalidOperation error stating existing_columns must be iterable. The adapter requires a list-like structure of column objects.
Source
Thrown at crates/dbt-adapter/src/adapter/adapter_impl.rs:4652
model_columns: &Value,
model_constraints: &Value,
contract_enforced: bool,
model_name: &str,
) -> Result<Value, minijinja::Error> {
use crate::relation::databricks::typed_constraint;
use std::collections::{BTreeMap, BTreeSet};
if self.adapter_type() != Databricks && self.adapter_type() != Spark {
return Err(minijinja::Error::new(
minijinja::ErrorKind::InvalidOperation,
"parse_columns_and_constraints is only available for Databricks/Spark adapter",
));
}
let columns: Vec<Column> = existing_columns
.try_iter()
.map_err(|e| {
minijinja::Error::new(
minijinja::ErrorKind::InvalidOperation,
format!("existing_columns must be iterable: {e}"),
)
})?
.map(|v| {
v.downcast_object_ref::<Column>().cloned().ok_or_else(|| {
minijinja::Error::new(
minijinja::ErrorKind::InvalidOperation,
"existing_columns must contain Column objects",
)
})
})
.collect::<Result<Vec<_>, _>>()?;
let model_columns_map: BTreeMap<String, DbtColumn> =
minijinja_value_to_typed_struct(model_columns.clone()).map_err(|e| {
minijinja::Error::new(
minijinja::ErrorKind::SerdeDeserializeError,View on GitHub (pinned to 0267ce9170)
Solutions
- Pass the output of get_columns_in_relation(relation) — a sequence of Column objects — as existing_columns.
- If you have a dict, convert it to a list of Column objects before calling.
- Check the error's inner message for what try_iter rejected and fix the value's type.
- Verify macro argument order wasn't swapped between existing_columns and model_columns.
Example fix
// before cols = model.columns # dict, not iterable sequence of Columns adapter.parse_columns_and_constraints(cols, model_columns, name) // after cols = adapter.get_columns_in_relation(target_relation) adapter.parse_columns_and_constraints(cols, model_columns, name)
Defensive patterns
Strategy: validation
Validate before calling
def is_iterable_columns(v):
try:
items = list(v)
except TypeError:
return False
return all(isinstance(i, dict) and 'name' in i for i in items) Type guard
def as_iterable(v):
try:
return list(v)
except TypeError:
return None Try / catch
try:
parsed = adapter.parse_columns_and_constraints(existing, model_columns, name)
except Exception as e:
if 'existing_columns must be iterable' in str(e):
existing = adapter.get_columns_in_relation(target_relation)
parsed = adapter.parse_columns_and_constraints(existing, model_columns, name)
else:
raise Prevention
- Feed existing_columns from get_columns_in_relation, not from config dicts
- Verify macro argument order (existing vs model columns)
- Add a shape assertion at the top of custom materializations
- Don't pass scalars or strings as existing_columns
When it happens
Trigger: Calling parse_columns_and_constraints with existing_columns as a non-iterable Value: a single object, a dict mapping names to columns, a string, or None.
Common situations: Passing a column dict from model.config instead of the relation's column list; forgetting that existing_columns comes from get_columns_in_relation (a sequence); macro refactors that changed the argument shape.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- existing_columns must contain Column objects
- only available with Databricksadapter
- only available with Databricks adapter
- resolve_file_format is only supported in Databricks
- update_tblproperties_for_uniform_iceberg is only supported i
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/9d1d17d2b6cc30e8.
Report an issue: GitHub.