dbt-labs/dbt-core · error
group_by with function key
Error message
group_by with function key
What it means
In dbt-agate's table object, group_by accepts a key that may be a string column name or (in upstream agate) a function. The Rust port only resolves string keys; when the key kwarg is not a string (e.g. a callable/function Value), it panics with unimplemented!("group_by with function key") instead of evaluating the function per row.
Source
Thrown at crates/dbt-agate/src/table.rs:1179
// :param key_type:
// An instance of any subclass of :class:`.DataType`. If not provided
// it will default to a :class`.Text`.
// :returns:
// A :class:`.TableSet` mapping where the keys are unique values from
// the :code:`key` and the values are new :class:`.Table` instances
// containing the grouped rows.
// """
// ```
"group_by" => {
let iter = ArgsIter::new("Table.group_by", &["key"], args);
let key = iter.next_arg::<&Value>()?;
let key_name = iter.next_kwarg::<Option<&Value>>("key_name")?;
let key_type = iter.next_kwarg::<Option<&Value>>("key_type")?;
iter.finish()?;
let key = match key.as_str() {
Some(s) => s,
None => unimplemented!("group_by with function key"),
};
let key_name = match key_name {
Some(v) => match v.as_str() {
Some(s) => s,
None => unimplemented!("group_by with non-string key_name"),
},
None => "group",
};
let key_type = match key_type {
Some(ty) => match ty.downcast_object_ref::<crate::DataType>() {
Some(dt) => Some(dt.clone()),
None => {
// TODO: support DataType class instances
unimplemented!("group_by with non-string key_type")
}
},
None => None,
};View on GitHub (pinned to 0267ce9170)
Solutions
- Group by an existing string column name instead of a function; pre-compute the derived values into a column first, then group_by that column name.
- Add a computed column to the table (table.compute / derive) holding the key expression's results, then call group_by("derived_col").
- If function keys are required, extend the Rust group_by to evaluate callable Values per row.
Example fix
// before
table.group_by(lambda_fn, key_name="k")
// after
table = table.compute([[lambda_fn, "k"]])
table.group_by("k", key_name="key_name") Defensive patterns
Strategy: validation
Validate before calling
{% if key is string %}
{% set grouped = table.group_by(key) %}
{% else %}
{% do exceptions.raise_compiler_error("group_by requires a string column key") %}
{% endif %} Type guard
fn is_string_key(v: &Value) -> bool { v.as_str().is_some() } Prevention
- Always pass a string column name to group_by in dbt-agate.
- Pre-compute derived grouping values into a column before grouping.
- When translating Python agate code, replace key functions with computed columns.
When it happens
Trigger: Calling table.group_by(key=<function or non-string Value>) from Jinja/Python-interop code — the key kwarg resolves via as_str() to None, hitting the unimplemented!() branch.
Common situations: Porting Python agate code that groups by a lambda/key function into dbt Jinja; macros that compute dynamic group keys with callables; passing a non-string key object (e.g. a computed column expression) to group_by.
Related errors
- ColumnsAsTuple::count_occurrences_of
- ColumnsAsTuple::index_of
- column_distinct
- RelationConfigBaseObject does not support method: {}
- {} relation creation from Jinja values
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/d1dc5d4703ab54dc.
Report an issue: GitHub.