dbt-labs/dbt-core · error
column must have a name attribute
Error message
column must have a name attribute
What it means
In the BigQuery partition filter (`reject_partition_field_column`) exposed to Jinja, each model `columns` entry is expected to expose a `name` attribute. `c.get_attr("name").expect(...)` panics when a column value lacks that attribute. The filter is used to exclude the partition field from column lists in rendered SQL, so any column-shaped value without `name` breaks the render with a Rust panic surfaced through the template engine.
Source
Thrown at crates/dbt-schemas/src/schemas/manifest/bigquery_partition.rs:186
"timestamp"
};
Ok(MinijinjaValue::from(data_type))
}
pub fn reject_partition_field_column(
&self,
args: &[MinijinjaValue],
) -> Result<MinijinjaValue, MinijinjaError> {
let mut parser = ArgParser::new(args, None);
parser.check_num_args(current_function_name!(), 0, 1)?;
let columns = parser.get::<MinijinjaValue>("columns")?;
if let Ok(iter) = columns.try_iter() {
let columns = iter
.filter(|c| {
let name = c
.get_attr("name")
.expect("column must have a name attribute");
!name
.as_str()
.expect("name attribute must be a string")
.eq_ignore_ascii_case(self.field.as_str())
})
.collect::<Vec<_>>();
Ok(MinijinjaValue::from(columns))
} else {
Err(MinijinjaError::new(
MinijinjaErrorKind::InvalidArgument,
"columns must be a list of Column",
))
}
}
/// Return true if the data type should be truncated instead of cast to the data type
pub fn data_type_should_be_truncated(&self) -> bool {
!(self.data_type == "int64"View on GitHub (pinned to 0267ce9170)
Solutions
- Ensure every entry in the model's `columns` config is a mapping with a `name` key in schema/YAML
- Check that the caller feeding `columns` into this filter passes parsed column structs (which always have `name`), not raw template values
- If you control the template, pre-filter columns for `name` presence before invoking the partition filter
Example fix
// before
let name = c.get_attr("name").expect("column must have a name attribute");
// after
let name = match c.get_attr("name") {
Ok(n) => n,
Err(_) => return true, // keep columns without a name
}; Defensive patterns
Strategy: validation
Validate before calling
// validate columns in the model config before rendering partition SQL
for col in &model.columns {
if col.get("name").map_or(true, |v| !v.is_string()) {
return Err("every column must have a string 'name' attribute".into());
}
} Type guard
fn has_string_name(col: &MinijinjaValue) -> bool {
col.get_attr("name").map(|n| n.as_str().is_some()).unwrap_or(false)
} Try / catch
let filtered = std::panic::catch_unwind(|| partition_cfg.reject_partition_field_column(columns));
Prevention
- Define schema column entries as mappings with a quoted string `name` key
- Quote numeric-looking column names in YAML (name: "2024")
- Lint model YAML so columns without `name` are rejected before execution
When it happens
Trigger: Rendering a BigQuery partition-related template (e.g. `partition_by` expressions) where the `columns` iterable contains values without a `name` attribute — e.g. columns defined as plain strings, dicts using a different key, or None entries in the model's `columns` config.
Common situations: A model config defines `columns` with non-standard shapes (lists of strings instead of `{name: ..., ...}` dicts); a custom/older adapter materialization passes malformed column values into the partition filter; hand-written YAML where column entries omit the `name` key.
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
- name attribute must be a string
- time_partitioning_field must be a string
- unknown table type: {type_string}
- when data_type is date, inner must be a TimeConfig
- adapter.parse_partition_by failed on {raw_partition_by:?}: {
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/f09c204647567778.
Report an issue: GitHub.