{"record":{"id":"07be4fcebeff4b27","repo":"dbt-labs/dbt-core","slug":"table-select-key-must-be-a-string-or-an-array-of","errorCode":null,"errorMessage":"Table.select: key must be a string or an array of strings: {e}","messagePattern":"Table\\.select: key must be a string or an array of strings: (.+?)","errorType":"validation","errorClass":"InvalidArgument","httpStatus":null,"severity":"error","filePath":"crates/dbt-agate/src/table.rs","lineNumber":1091,"sourceCode":"                //\n                //     :param key:\n                //         Either the name of a single column to include or a sequence of such\n                //         names.\n                //     :returns:\n                //         A new :class:`.Table`.\n                //     \"\"\"\n                // ```\n                let iter = ArgsIter::new(\"Table.select\", &[\"key\"], args);\n                let key = iter.next_arg::<&Value>()?;\n                iter.finish()?;\n\n                let keys = if let Some(single_key) = key.as_str() {\n                    Vec::from([single_key.to_string()])\n                } else {\n                    let iter = match key.try_iter() {\n                        Ok(iter) => iter,\n                        Err(e) => {\n                            return Err(Error::new(\n                                ErrorKind::InvalidArgument,\n                                format!(\n                                    \"Table.select: key must be a string or an array of strings: {e}\"\n                                ),\n                            ));\n                        }\n                    };\n                    let mut keys = Vec::new();\n                    for v in iter {\n                        if let Some(s) = v.as_str() {\n                            keys.push(s.to_string());\n                        } else {\n                            return Err(Error::new(\n                                ErrorKind::InvalidArgument,\n                                format!(\n                                    \"Table.select: key must be a string or an array of strings: {v} found instead\"\n                                ),\n                            ));","sourceCodeStart":1073,"sourceCodeEnd":1109,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-agate/src/table.rs#L1073-L1109","documentation":"Thrown by `Table.select()` when the `key` argument cannot be interpreted as a string or an array of strings. The library first tries to read the key as a single string; if that fails and the value cannot be iterated as a list, this InvalidArgument error is raised. Agate's `select` requires column names, so anything else (number, dict, non-string elements path) is rejected.","triggerScenarios":"Calling `table.select(key)` where `key` is not a str and `key.try_iter()` fails — e.g. an integer, a non-iterable object, or a malformed value passed as the column selector.","commonSituations":"Passing a column index instead of a column name, passing a tuple/set from scripting, or programmatically building the key list and accidentally passing a scalar.","solutions":["Pass column names as a string: `table.select('col')`","Pass a list of strings: `table.select(['col1', 'col2'])`","Cast non-string keys to strings before calling select","Log/inspect the type of the key value being passed"],"exampleFix":"// before\ntable.select(0)\n// after\ntable.select('column_name')  # or table.select(['a', 'b'])","handlingStrategy":"type-guard","validationCode":"def ensure_select_key(key):\n    if isinstance(key, str):\n        return [key]\n    if isinstance(key, (list, tuple)) and all(isinstance(k, str) for k in key):\n        return list(key)\n    raise ValueError('key must be a string or list of strings')","typeGuard":"def is_str_or_str_list(v):\n    return isinstance(v, str) or (isinstance(v, (list, tuple)) and all(isinstance(k, str) for k in v))","tryCatchPattern":"try:\n    result = table.select(key)\nexcept Exception as e:\n    if 'key must be a string or an array of strings' in str(e):\n        result = table.select(ensure_select_key(key))\n    else:\n        raise","preventionTips":["Always pass column names as strings, never indices","Normalize keys with a helper before calling select","Add unit tests for dynamically built key lists"],"tags":["rust","type-error","argument-validation"],"backgroundTag":"invalid-argument-value","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"}