dbt-labs/dbt-core · error · InvalidArgument
Table.select: key must be a string or an array of strings: {
Error message
Table.select: key must be a string or an array of strings: {e} What it means
Thrown by `Table.select()` when the `key` argument cannot be interpreted as a string or an array of strings. The library first tries to read the key as a single string; if that fails and the value cannot be iterated as a list, this InvalidArgument error is raised. Agate's `select` requires column names, so anything else (number, dict, non-string elements path) is rejected.
Source
Thrown at crates/dbt-agate/src/table.rs:1091
//
// :param key:
// Either the name of a single column to include or a sequence of such
// names.
// :returns:
// A new :class:`.Table`.
// """
// ```
let iter = ArgsIter::new("Table.select", &["key"], args);
let key = iter.next_arg::<&Value>()?;
iter.finish()?;
let keys = if let Some(single_key) = key.as_str() {
Vec::from([single_key.to_string()])
} else {
let iter = match key.try_iter() {
Ok(iter) => iter,
Err(e) => {
return Err(Error::new(
ErrorKind::InvalidArgument,
format!(
"Table.select: key must be a string or an array of strings: {e}"
),
));
}
};
let mut keys = Vec::new();
for v in iter {
if let Some(s) = v.as_str() {
keys.push(s.to_string());
} else {
return Err(Error::new(
ErrorKind::InvalidArgument,
format!(
"Table.select: key must be a string or an array of strings: {v} found instead"
),
));View on GitHub (pinned to 0267ce9170)
Solutions
- Pass column names as a string: `table.select('col')`
- Pass a list of strings: `table.select(['col1', 'col2'])`
- Cast non-string keys to strings before calling select
- Log/inspect the type of the key value being passed
Example fix
// before
table.select(0)
// after
table.select('column_name') # or table.select(['a', 'b']) Defensive patterns
Strategy: type-guard
Validate before calling
def ensure_select_key(key):
if isinstance(key, str):
return [key]
if isinstance(key, (list, tuple)) and all(isinstance(k, str) for k in key):
return list(key)
raise ValueError('key must be a string or list of strings') Type guard
def is_str_or_str_list(v):
return isinstance(v, str) or (isinstance(v, (list, tuple)) and all(isinstance(k, str) for k in v)) Try / catch
try:
result = table.select(key)
except Exception as e:
if 'key must be a string or an array of strings' in str(e):
result = table.select(ensure_select_key(key))
else:
raise Prevention
- Always pass column names as strings, never indices
- Normalize keys with a helper before calling select
- Add unit tests for dynamically built key lists
When it happens
Trigger: Calling `table.select(key)` where `key` is not a str and `key.try_iter()` fails — e.g. an integer, a non-iterable object, or a malformed value passed as the column selector.
Common situations: Passing a column index instead of a column name, passing a tuple/set from scripting, or programmatically building the key list and accidentally passing a scalar.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Table.select: key must be a string or an array of strings: {
- Table.join: right_table must be a Table: {right_table} found
- Table.rename: column_names array must contain only strings,
- Table.rename: row_names array must contain only strings, fou
- A join can not be both "inner" and "full_outer".
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/07be4fcebeff4b27.
Report an issue: GitHub.