{"record":{"id":"2b1564a70fd22277","repo":"dbt-labs/dbt-core","slug":"table-join-columns-must-be-a-sequence-of-column-n-2b1564","errorCode":null,"errorMessage":"Table.join: columns must be a sequence of column names: {column} found instead","messagePattern":"Table\\.join: columns must be a sequence of column names: (.+?) found instead","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbt-agate/src/join.rs","lineNumber":118,"sourceCode":"//\n// `None` means \"all columns not in right_key\" (the default), `Some([])` means\n// \"no columns\", and `Some([name1, name2, ...])` means \"only these columns\".\nfn selected_right_table_columns(columns: Option<&Value>) -> Result<Option<Vec<String>>, Error> {\n    let Some(columns) = columns else {\n        return Ok(None);\n    };\n    let iter = columns.try_iter().map_err(|e| {\n        Error::new(\n            ErrorKind::InvalidArgument,\n            format!(\"Table.join: columns must be a sequence of column names: {e}\"),\n        )\n    })?;\n    let mut names = Vec::new();\n    for column in iter {\n        match column.as_str() {\n            Some(name) => names.push(name.to_string()),\n            None => {\n                return Err(Error::new(\n                    ErrorKind::InvalidArgument,\n                    format!(\n                        \"Table.join: columns must be a sequence of column names: {column} found instead\"\n                    ),\n                ));\n            }\n        }\n    }\n    Ok(Some(names))\n}\n\nimpl AgateTable {\n    pub fn join(\n        &self,\n        right_table: &AgateTable,\n        left_key: Option<&Value>,\n        right_key: Option<&Value>,\n        join_type: JoinType,","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-agate/src/join.rs#L100-L136","documentation":"Raised in selected_right_table_columns while validating the `columns` argument of Table.join in the Agate table emulation. The Jinja value passed as `columns` is not iterable (not a list/tuple of column-name strings), so try_iter() fails and the underlying type error is wrapped into this InvalidArgument message. The input at fault is the caller's `columns` keyword in the Jinja join() call.","triggerScenarios":"Thrown at crates/dbt-agate/src/join.rs:118 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Pass a sequence of column-name strings, e.g. table.join(other, left_key='id', right_key='id', columns=['name', 'amount'])","Pass a list of strings rather than a single string, a dict, or an integer","Omit `columns` entirely to select all non-key right-table columns"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}