{"record":{"id":"95cf14ba7ea97d10","repo":"dbt-labs/dbt-core","slug":"table-rename-column-names-must-be-a-map-or-an-arr","errorCode":null,"errorMessage":"Table.rename: column_names must be a map or an array","messagePattern":"Table\\.rename: column_names must be a map or an array","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbt-agate/src/table.rs","lineNumber":679,"sourceCode":"                                if key.as_str().is_some_and(|k| k == col) {\n                                    renamed[i] = value.to_string();\n                                }\n                            }\n                        }\n                        renamed\n                    }};\n                }\n                if let Some(map) = v.downcast_object_ref::<ValueMap>() {\n                    Ok(rename_columns_by_map!(map))\n                } else if let Some(map) = v.downcast_object_ref::<MutableMap>() {\n                    let map: ValueMap = map.clone().into();\n                    Ok(rename_columns_by_map!(map))\n                } else {\n                    // Try to treat it as a generic iterable\n                    let iter = match v.try_iter() {\n                        Ok(iter) => iter,\n                        Err(_) => {\n                            return Err(Error::new(\n                                ErrorKind::InvalidArgument,\n                                \"Table.rename: column_names must be a map or an array\",\n                            ));\n                        }\n                    };\n                    let mut renamed = old;\n                    for (i, value) in iter.enumerate() {\n                        if i >= renamed.len() {\n                            break;\n                        }\n                        if let Some(s) = value.as_str() {\n                            renamed[i] = s.to_string();\n                        } else {\n                            return Err(Error::new(\n                                ErrorKind::InvalidArgument,\n                                format!(\n                                    \"Table.rename: column_names array must contain only strings, found: {}\",\n                                    value","sourceCodeStart":661,"sourceCodeEnd":697,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-agate/src/table.rs#L661-L697","documentation":"Table.rename was called with a column_names argument that is neither a map (old-name -> new-name) nor an array of new column names. The library attempts to interpret the value as a generic iterable when it is not a map, and throws this error if the value cannot be iterated at all. This mirrors agate's Python rename(), which accepts only mappings or sequences for column_names.","triggerScenarios":"Calling table.rename with column_names set to a scalar (e.g. a string instead of an array of strings), an integer, a struct without iteration support, or a non-iterable value instead of a map/array.","commonSituations":"Passing a single string like \"col_a\" instead of [\"col_a\", \"col_b\"]; passing a hash-map-like object that the bridge cannot convert; porting Python agate code where column_names was a dict and the Rust binding expects a map or array.","solutions":["Pass column_names as a map of old column name to new column name, e.g. {\"old\": \"new\"}.","Pass column_names as a plain array of new column name strings, one per column.","Omit column_names entirely if you only intend to rename rows."],"exampleFix":"// before\ntable.rename(\"new_name\", None, false, false)\n// after\ntable.rename(Some(vec![\"new_name\"]), None, false, false)","handlingStrategy":"validation","validationCode":"fn valid_column_names(v: &Value) -> bool {\n    v.as_map().is_some()\n        || v.as_array().map_or(false, |a| a.iter().all(|x| x.as_str().is_some()))\n}","typeGuard":"fn is_name_spec(v: &Value) -> bool {\n    v.as_map().is_some()\n        || v.as_array().map_or(false, |a| a.iter().all(|x| x.as_str().is_some()))\n}","tryCatchPattern":"match table.rename(column_names, row_names, false, false) {\n    Ok(t) => t,\n    Err(e) if e.to_string().contains(\"column_names must be a map or an array\") => {\n        eprintln!(\"column_names must be a map or array of strings: {e}\");\n        table.rename(default_names, None, false, false)?\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Always pass a map or a Vec<String> for column_names.","Never pass a bare string where an array of names is expected.","Validate argument types before calling rename, especially when values come from config or JSON."],"tags":["argument-validation","rename","agate"],"backgroundTag":"invalid-argument-format","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}