dbt-labs/dbt-core · error

Table.rename: row_names must be a map or an array

Error message

Table.rename: row_names must be a map or an array

What it means

Table.rename was called with a row_names argument that is neither a map (old row-name -> new row-name) nor an array of new row names. Like the column_names case, the value is probed for iteration and this error is thrown if it cannot be iterated.

Source

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

                                    renamed.append_value(old_name);
                                }
                            } else {
                                renamed.append_null();
                            }
                        }
                        Arc::new(renamed.finish())
                    }};
                }
                if let Some(map) = v.downcast_object_ref::<ValueMap>() {
                    Ok(rename_rows_by_map!(map))
                } else if let Some(map) = v.downcast_object_ref::<MutableMap>() {
                    Ok(rename_rows_by_map!(map))
                } else {
                    // 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: row_names must be a map or an array",
                            ));
                        }
                    };

                    // Collect the iterator values
                    let values: Vec<_> = iter.collect();

                    for i in 0..self.num_rows() {
                        if let Some(value) = values.get(i) {
                            if let Some(s) = value.as_str() {
                                renamed.append_value(s);
                            } else {
                                return Err(Error::new(
                                    ErrorKind::InvalidArgument,
                                    format!(
                                        "Table.rename: row_names array must contain only strings, found: {}",

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Pass row_names as a map of old row name to new row name.
  2. Pass row_names as an array of new row name strings, one per row.
  3. Omit row_names if you only intend to rename columns.

Example fix

// before
table.rename(None, Some("row0"), false, false)
// after
table.rename(None, Some(vec!["row0"]), false, false)
Defensive patterns

Strategy: validation

Validate before calling

fn valid_row_names(v: &Value) -> bool {
    v.as_map().is_some()
        || v.as_array().map_or(false, |a| a.iter().all(|x| x.as_str().is_some()))
}

Type guard

fn is_row_name_spec(v: &Value) -> bool {
    v.as_map().is_some()
        || v.as_array().map_or(false, |a| a.iter().all(|x| x.as_str().is_some()))
}

Try / catch

match table.rename(None, row_names, false, false) {
    Ok(t) => t,
    Err(e) if e.to_string().contains("row_names must be a map or an array") => {
        eprintln!("row_names must be a map or array of strings: {e}");
        table.rename(None, None, false, false)?
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling table.rename with row_names set to a scalar, integer, or non-iterable object, e.g. passing a single row name string instead of a list of names.

Common situations: Porting Python agate code that used a dict for row_names; passing a single value when a sequence was expected; config values parsed as the wrong type.

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


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