{"record":{"id":"ef7f7193ae6e64c2","repo":"dbt-labs/dbt-core","slug":"columnsastuple-index-of","errorCode":null,"errorMessage":"ColumnsAsTuple::index_of","messagePattern":"ColumnsAsTuple::index_of","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbt-agate/src/columns.rs","lineNumber":216,"sourceCode":"    }\n}\n\nimpl TupleRepr for ColumnsAsTuple {\n    fn get_item_by_index(&self, idx: isize) -> Option<Value> {\n        let column = self.of_table.get_column(idx)?;\n        Some(Value::from_object(column))\n    }\n\n    fn len(&self) -> usize {\n        self.of_table.num_columns()\n    }\n\n    fn count_occurrences_of(&self, _needle: &Value) -> usize {\n        todo!(\"ColumnsAsTuple::count_occurrences_of\")\n    }\n\n    fn index_of(&self, _needle: &Value) -> Option<usize> {\n        todo!(\"ColumnsAsTuple::index_of\")\n    }\n\n    fn clone_repr(&self) -> Box<dyn TupleRepr> {\n        Box::new(ColumnsAsTuple {\n            of_table: Arc::clone(&self.of_table),\n        })\n    }\n}\n\n/// Represents an instance of a `MappedSequence` populated by a list of columns.\n///\n/// https://github.com/wireservice/agate/blob/7023e35b51e8abfe9784fe292a23dd4d7d983c63/agate/table/__init__.py#L181\n#[derive(Debug)]\npub struct Columns {\n    /// Internal representation of the columns sequence is the table representation itself.\n    of_table: Arc<TableRepr>,\n}\n","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-agate/src/columns.rs#L198-L234","documentation":"`ColumnsAsTuple::index_of` in dbt-agate is a `todo!()` placeholder in the `TupleRepr` trait implementation, so calling it panics with \"ColumnsAsTuple::index_of\". The columns-as-tuple view cannot yet locate the position of a value among a table's columns. Any tuple-style `index_of` lookup against the table's column collection panics.","triggerScenarios":"Calling `index_of(&value)` on a `ColumnsAsTuple` for any needle value, e.g., asking which column equals a given value.","commonSituations":"Porting Python agate code that calls `.index(...)` on a table's columns tuple to the Rust dbt-agate port; generic tuple-repr algorithms that fall back to `index_of`.","solutions":["Avoid `index_of` on the columns tuple view; find the column position by iterating column names/values manually.","Use a representation that implements `index_of` (e.g., row tuples) if applicable.","Implement the method upstream: iterate columns in order and return `Some(i)` for the first column equal to the needle, else `None`."],"exampleFix":"// before (crates/dbt-agate/src/columns.rs)\nfn index_of(&self, _needle: &Value) -> Option<usize> {\n    todo!(\"ColumnsAsTuple::index_of\")\n}\n// after\nfn index_of(&self, needle: &Value) -> Option<usize> {\n    (0..self.len()).find(|&i| self.get(i).map_or(false, |v| v == needle))\n}","handlingStrategy":"validation","validationCode":"// avoid the call; find the column position manually:\nlet idx = (0..table.num_columns())\n    .find(|&i| table.column_value(i) == *needle);","typeGuard":"fn supports_index_of(repr: &dyn TupleRepr) -> bool {\n    (repr as &dyn std::any::Any).downcast_ref::<ColumnsAsTuple>().is_none()\n}","tryCatchPattern":"// isolate the placeholder if unavoidable:\nlet idx = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| repr.index_of(&needle)))\n    .unwrap_or(None);","preventionTips":["Look up column positions via column names/indices instead of tuple-style index_of.","Use representations whose TupleRepr methods are fully implemented.","Grep for todo!() in dbt-agate before relying on a trait method for ColumnsAsTuple."],"tags":["unimplemented","agate","rust-panic","table-operations"],"backgroundTag":"method-not-implemented","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"}