dbt-labs/dbt-core · error

Table.rename: column_names array must contain only strings,

Error message

Table.rename: column_names array must contain only strings, found: {}

What it means

When column_names is given as an array to Table.rename, every element must be a string (the new column name). The library found a non-string element while assigning new names positionally and includes the offending value in the message.

Source

Thrown at crates/dbt-agate/src/table.rs:693

                    // Try to treat it as a generic iterable
                    let iter = match v.try_iter() {
                        Ok(iter) => iter,
                        Err(_) => {
                            return Err(Error::new(
                                ErrorKind::InvalidArgument,
                                "Table.rename: column_names must be a map or an array",
                            ));
                        }
                    };
                    let mut renamed = old;
                    for (i, value) in iter.enumerate() {
                        if i >= renamed.len() {
                            break;
                        }
                        if let Some(s) = value.as_str() {
                            renamed[i] = s.to_string();
                        } else {
                            return Err(Error::new(
                                ErrorKind::InvalidArgument,
                                format!(
                                    "Table.rename: column_names array must contain only strings, found: {}",
                                    value
                                ),
                            ));
                        }
                    }
                    Ok(renamed)
                }
            })
            .transpose()?;

        // Renaming of rows
        let old_row_name = |i| -> Option<&str> {
            self.repr.row_names.as_ref().and_then(|names| {
                if names.as_ref().is_valid(i) {
                    Some(names.value(i))

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Ensure every element of the column_names array is a string before calling rename.
  2. Convert numeric or other elements with a string conversion step, e.g. value.to_string().
  3. Use the map form {"old": "new"} instead if you want selective renaming.

Example fix

// before
rename(Some(vec!["a", 2]), None, false, false)
// after
rename(Some(vec!["a", "b"]), None, false, false)
Defensive patterns

Strategy: type-guard

Validate before calling

let all_strings = column_names.iter().all(|v| v.as_str().is_some());
if !all_strings { panic!("column_names must contain only strings"); }

Type guard

fn all_strings(v: &[Value]) -> bool {
    v.iter().all(|x| x.as_str().is_some())
}

Try / catch

match result {
    Err(e) if e.to_string().contains("array must contain only strings") => {
        let coerced: Vec<String> = raw_names.iter().map(|v| v.to_string()).collect();
        table.rename(Some(coerced), None, false, false)?
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling table.rename with an array column_names containing numbers, nulls, booleans, or nested values, e.g. ["a", 2, null].

Common situations: Programmatically building the name list from mixed sources (parsed CSV headers mixed with placeholders); JSON config where names were numbers; forgetting to stringify values read from a config file.

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


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/e2601aafa6a4e6a4. Report an issue: GitHub.