dbt-labs/dbt-core · error
column identifier must be a column name or a column index
Error message
column identifier must be a column name or a column index: {key} found instead What it means
Validation in Table::column_index_of: the Jinja value used as a column identifier is neither a string (column name) nor an integer (column index). The offending value is interpolated as {key}; the caller passed an unusable type where a name or index was expected.
Solutions
- Pass a column name string or a zero-based column index integer
- Wrap multiple identifiers in a list instead of passing a dict or other object
- Check that the identifier value is not None/undefined in the template
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at crates/dbt-agate/src/table.rs:167 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/bb9b5e9e4ad7e879.
Report an issue: GitHub.
Appendix: source
Thrown at crates/dbt-agate/src/table.rs:167
pub fn column_indices<'a>(&'a self, keys: &'a [String]) -> impl Iterator<Item = usize> + 'a {
let fields = self.flat.schema_ref().as_ref().fields();
let iter = keys
.iter()
.filter_map(|k| fields.iter().position(|f| f.name() == k));
iter
}
/// Index of the column with the given name or at the given index.
///
/// `None` if the name is not found or the index is out of range.
fn column_index_of(&self, key: &Value) -> Result<Option<usize>, Error> {
if let Some(name) = key.as_str() {
let fields = self.flat.schema_ref().as_ref().fields();
Ok(fields.iter().position(|f| f.name() == name))
} else if let Some(idx) = key.as_i64() {
Ok(adjusted_index(idx as isize, self.num_columns()))
} else {
Err(Error::new(
ErrorKind::InvalidArgument,
format!(
"column identifier must be a column name or a column index: {key} found instead"
),
))
}
}
/// Indices of the columns identified by a Jinja value.
///
/// `keys` may be a single column name, a single column index, or a sequence of
/// either (the two can be mixed).
///
/// If a key is not found, it is simply skipped,
pub fn column_indices_of(&self, keys: &Value) -> Result<Vec<usize>, Error> {
// Strings are iterable in Jinja (by character), so single identifiers have to
// be handled before falling back to the sequence case below.
if keys.as_str().is_some() || keys.as_i64().is_some() {View on GitHub (pinned to 0267ce9170)