dbt-labs/dbt-core · error

AgateTable

Error message

AgateTable::{}

What it means

The Rust AgateTable object's call_method dispatch only implements a fixed set of Table methods; calling any other method name falls through to unimplemented!("AgateTable::{}"), naming the missing method. This indicates the requested Table API is not yet bridged in dbt-agate.

Solutions

  1. Check the match arms in crates/dbt-agate/src/table.rs (Object impl) for the list of implemented methods and use only those
  2. Implement the missing method arm in the Object::call_method match, following existing arms like "distinct"
  3. Work around by using implemented primitives (select, group_by, distinct) to emulate the missing method

Example fix

// before
table.call_method("exclude", args![Value::from("secret_col")])  // panics: AgateTable::exclude
// after
let keep: Vec<_> = table.column_names().into_iter().filter(|c| c != "secret_col").map(Value::from).collect();
table.call_method("select", args![Value::from(keep)])
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED: &[&str] = &["select", "group_by", "distinct", "aggregate", /* ... */];
assert!(SUPPORTED.contains(&method_name), "AgateTable method not implemented: {}", method_name);

Prevention

When it happens

Trigger: Invoking any agate Table method not covered by the match arms in the Object impl for AgateTable (e.g. table.homogenize(), table.exclude(), or any misspelled method name).

Common situations: Porting Python agate scripts that use methods not yet implemented in the Rust bridge; typo'd method names; relying on agate's full Python API surface from Rust/dbt integration code.

Related errors


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/d9de1695a8945140. Report an issue: GitHub.

Appendix: source

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

                                match key.as_str() {
                                    Some(s) => keys.push(s.to_string()),
                                    None => unimplemented!("distinct with non-string keys"),
                                }
                            }
                            Some(keys)
                        } else {
                            None
                        }
                    }
                    None => None,
                };

                let result = self.as_ref().distinct(key).map_err(|e| {
                    Error::new(ErrorKind::InvalidOperation, format!("Table.distinct: {e}"))
                })?;
                Ok(Value::from_object(result))
            }
            other => unimplemented!("AgateTable::{}", other),
        }
    }
}

#[cfg(test)]
mod tests {
    use crate::flat_record_batch::FlatRecordBatch;
    use crate::test_fixtures::*;
    use crate::*;
    use arrow::array::{
        ArrayRef, BooleanBuilder, DictionaryArray, Float64Builder, Int32Array, Int32Builder,
        ListBuilder, StringBuilder, StringViewBuilder, StructBuilder,
    };
    use arrow::array::{GenericListArray, StringArray};
    use arrow::csv::reader::ReaderBuilder;
    use arrow::datatypes::{DataType, Field, Int32Type, Schema};
    use arrow::record_batch::RecordBatch;
    use arrow_array::{Array, ListArray, RecordBatchOptions, UInt64Array};

View on GitHub (pinned to 0267ce9170)