TanStack/table · warning
aggregationFn '${String(ref)}' for column '${column.id}' is
Error message
aggregationFn '${String(ref)}' for column '${column.id}' is not registered What it means
`resolveAggregationFn` maps a column's `aggregationFn` ref: function/definition objects pass through, `'auto'` delegates to auto-detection, and string refs are looked up in `table._rowModelFns.aggregationFns`. This warning fires when a string ref has no registry entry, so `column_getAggregationFns` resolves it to `undefined` and the aggregated cell renders empty. It is a dev-only signal that the referenced aggregation function name was never registered for this table instance.
Source
Thrown at packages/table-core/src/features/row-aggregation/rowAggregationFeature.utils.ts:223
}
return aggregationFn
}
function resolveAggregationFn<
TFeatures extends TableFeatures,
TData extends RowData,
>(
column: Column_Internal<TFeatures, TData, any>,
ref: AggregationFnRef<TFeatures, TData, any, any>,
): AggregationFnDef<TFeatures, TData, any, any> | undefined {
if (isAggregationFnDef(ref)) return ref as any
if (ref === 'auto') return column_getAutoAggregationFn(column)
const aggregationFn =
column.table._rowModelFns.aggregationFns?.[ref as string]
if (!aggregationFn) {
warn(
`aggregationFn '${String(ref)}' for column '${column.id}' is not registered`,
)
}
return aggregationFn
}
/** Resolves and validates a column's scalar or multiple aggregation option. */
export function column_getAggregationFns<
TFeatures extends TableFeatures,
TData extends RowData,
TValue extends CellData = CellData,
>(
column: Column_Internal<TFeatures, TData, TValue>,
): ReadonlyArray<ResolvedAggregationFn<TFeatures, TData>> {
const option = column.columnDef.aggregationFn
const registry = column.table._rowModelFns.aggregationFns
const coreRowModel = column.table.getCoreRowModel()
const previous = (column as any)._resolvedAggregationFnsCache asView on GitHub (pinned to d01c01bedb)
Solutions
- Compare the string in the warning with `Object.keys(table._rowModelFns.aggregationFns ?? {})` and fix the key/ref mismatch.
- Register the missing function under that exact name in the aggregationFns registry.
- Pass the aggregation definition object directly (`{ aggregate(...) {...} }`) instead of a string name.
- If the intent was auto-detection, use the literal `'auto'` rather than an unregistered name.
- Ensure registry identity is stable: create the aggregationFns record once (module scope or useMemo) so lookups keep resolving.
Example fix
// before
{ header: 'Total', accessorKey: 'amount', aggregationFn: 'sumAll' } // not registered
// after
{ header: 'Total', accessorKey: 'amount', aggregationFn: 'sum' } // key exists in aggregationFns Defensive patterns
Strategy: type-guard
Validate before calling
function assertAggregationRefRegistered(ref: unknown, fns: Record<string, unknown> | undefined) {
if (typeof ref === 'string' && ref !== 'auto' && (!fns || !(ref in fns))) {
throw new Error(`aggregationFn '${ref}' not registered. Available: ${Object.keys(fns ?? {}).join(', ')}`)
}
} Type guard
function isRegisteredAggregationRef(
ref: unknown,
fns: Record<string, unknown> | undefined,
): ref is string {
return (
typeof ref === 'string' &&
(ref === 'auto' || (!!fns && ref in fns))
)
} Try / catch
try {
const entries = column.getAggregationFns()
for (const entry of entries) {
if (entry.aggregationFn === undefined) {
console.warn(`column aggregation '${entry.id}' unresolved — check registry`)
}
}
} catch (e) {
console.error('aggregation fn resolution failed', e)
} Prevention
- Define aggregation fn names as a const object and derive both registry keys and columnDef refs from it (single source of truth).
- Write a test that resolves every aggregationFn ref used in your column defs.
- Pass definition objects instead of strings when the fn is local to the component.
When it happens
Trigger: Setting `aggregationFn: 'sum'` / `'mean'` / any custom string on a columnDef while the table's `aggregationFns` registry omits that exact key; typo or case mismatch in the ref; registry object replaced after table creation while the option string stayed; array-valued options where one element is an unregistered string.
Common situations: Renaming custom aggregation fns during refactors; copy-pasting columnDefs between projects with different registries; forgetting to register a new custom aggregation before using it in a column.
Related errors
- globalFilterFn '${String(globalFilterFn)}' is not registered
- ${message}
- aggregationFn at index ${i} for column '${column.id}' needs
- aggregationFn id '${id}' for column '${column.id}' is duplic
- aggregationFn '${name}' (auto) for column '${column.id}' is
AI-assisted analysis of TanStack/table@d01c01bedb (2026-08-28).
Data as JSON: /api/errors/9662e81b9059114a.
Report an issue: GitHub.