dbt-labs/dbt-core · error

Table.rename: renamed_columns length ({}) does not match num

Error message

Table.rename: renamed_columns length ({}) does not match number of columns ({})

What it means

Table.rename validates that a provided renamed_columns array has exactly one entry per column of the table. The array's length did not match the table's column count, so the positional renaming would be ambiguous and the call is rejected.

Source

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

    }

    /// Rename columns and/or rows.
    ///
    /// PRECONDITION:
    /// - if `renamed_columns` is `Some`, its length must be equal to
    ///   the number of columns in the table.
    /// - if `renamed_rows` is `Some`, its length must be equal to
    ///   the number of rows in the table.
    pub fn rename(
        &self,
        renamed_columns: Option<Vec<String>>,
        renamed_rows: Option<Arc<StringViewArray>>,
        slug_columns: bool,
        slug_rows: bool,
    ) -> Result<AgateTable, Error> {
        if let Some(ref columns) = renamed_columns {
            if columns.len() != self.num_columns() {
                return Err(Error::new(
                    ErrorKind::InvalidArgument,
                    format!(
                        "Table.rename: renamed_columns length ({}) does not match number of columns ({})",
                        columns.len(),
                        self.num_columns()
                    ),
                ));
            }
        }
        if let Some(ref rows) = renamed_rows {
            if rows.len() != self.num_rows() {
                return Err(Error::new(
                    ErrorKind::InvalidArgument,
                    format!(
                        "Table.rename: renamed_rows length ({}) does not match number of rows ({})",
                        rows.len(),
                        self.num_rows()
                    ),

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Compute the name list from the table's actual column count (num_columns) before calling rename.
  2. Use the map form {"old": "new"} to rename only selected columns without matching lengths.
  3. Print the table's column count and the array length to find where they diverge.

Example fix

// before
rename(Some(vec!["a", "b"]), None, false, false) // table has 3 columns
// after
rename(Some(vec!["a", "b", "c"]), None, false, false)
Defensive patterns

Strategy: validation

Validate before calling

if renamed.len() != table.num_columns() {
    return Err(format!("expected {} names, got {}", table.num_columns(), renamed.len()));
}

Try / catch

match result {
    Err(e) if e.to_string().contains("renamed_columns length") => {
        eprintln!("{e}; check table schema and name list sizes");
        // rebuild names from table.num_columns() and retry
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling rename with an array of new column names shorter or longer than the table's number of columns, e.g. renaming a 5-column table with a 3-element array.

Common situations: Reusing a hardcoded name list against a table whose schema changed after upstream transformations; building the list before knowing the final column set; copy-pasted rename calls from another table.

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/c59d9a4413444e1e. Report an issue: GitHub.