dbt-labs/dbt-core · error

Table.rename: renamed_rows length ({}) does not match number

Error message

Table.rename: renamed_rows length ({}) does not match number of rows ({})

What it means

Table.rename validates that a provided renamed_rows array has exactly one entry per row of the table. A length mismatch was found, so positional row renaming would be ambiguous and the call is rejected.

Source

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

        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()
                    ),
                ));
            }
        }

        if slug_columns || slug_rows {
            return Err(Error::new(
                ErrorKind::InvalidOperation,
                "Table.rename: slugging columns or rows is not implemented yet",
            ));
        }

        let repr = if let Some(renamed_columns) = renamed_columns {

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Build the renamed_rows array from the table's current row count (num_rows) right before calling rename.
  2. Use the map form for row_names to rename only specific rows.
  3. Re-check any upstream filtering/aggregation that changed the number of rows.

Example fix

// before
rename(None, Some(vec!["r0", "r1"]), false, false) // table has 5 rows
// after
rename(None, Some(vec!["r0", "r1", "r2", "r3", "r4"]), false, false)
Defensive patterns

Strategy: validation

Validate before calling

if renamed_rows.len() != table.num_rows() {
    return Err(format!("expected {} row names, got {}", table.num_rows(), renamed_rows.len()));
}

Try / catch

match result {
    Err(e) if e.to_string().contains("renamed_rows length") => {
        eprintln!("{e}; rebuild row name list from table.num_rows()");
        // rebuild names and retry
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling rename with renamed_rows whose length differs from the table's row count, e.g. renaming a 10-row table with a 4-element array.

Common situations: Renaming rows after a filter/aggregate changed the row count; hardcoding lengths from a snapshot of the data; concatenating partial name lists.

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