gohugoio/hugo · error
grouping not supported for type %T %T
Error message
grouping not supported for type %T %T
What it means
Returned by the collections.Group template function when neither items nor its slice element implements collections.Grouper. Group first checks items for the Grouper interface, then newSliceElement(items); if both fail it errors with %T %T showing the outer and element types. Grouping is currently only supported for Pages (and types implementing Grouper).
Solutions
- Pass a Pages collection (e.g. `.Site.RegularPages`) to group; that is the supported input.
- For non-page data, pre-group in your template using `slice`/`range`/a partial instead of the `group` function.
- If grouping a custom type, implement the collections.Grouper interface on its slice element so Group can dispatch to it.
Example fix
// before
{{ $groups := group "date" .Params.posts }}
// after
{{ $groups := group "date" .Site.RegularPages }} Defensive patterns
Strategy: type-guard
Validate before calling
// Guard that items implements Grouper (Pages do) before grouping.
func isGrouper(v any) bool {
_, ok1 := v.(collections.Grouper)
if ok1 { return true }
// also check slice element
rv := reflect.ValueOf(v)
if rv.Kind() == reflect.Slice && rv.Len() > 0 {
_, ok2 := rv.Index(0).Interface().(collections.Grouper)
return ok2
}
return false
} Type guard
// Go type guard for Grouper interface.
func asGrouper(v any) (collections.Grouper, bool) {
g, ok := v.(collections.Grouper)
return g, ok
} Prevention
- Only call group on Pages collections (e.g. .Site.RegularPages).
- For custom data, group manually with range/slice instead of the group function.
- Implement Grouper on custom collection element types if you need group support.
When it happens
Trigger: Calling `group key items` in a template where items is not a Pages collection or a type that implements Grouper — e.g. a slice of plain maps, strings, or a single Page. The function requires a collection whose element type knows how to group itself.
Common situations: Trying to group a slice of dict/strings, grouping a single object instead of .Pages, or grouping a custom data list that doesn't implement the Grouper interface.
Related errors
- argument must be a slice
- can't apply over
- can't iterate over %T
- incompatible map types, got %T to %T
- nil is not a valid key to group by
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/e43959e22586e983.
Report an issue: GitHub.
Appendix: source
Thrown at tpl/collections/collections.go:327
// Group groups a set of items by the given key.
// This is currently only supported for Pages.
func (ns *Namespace) Group(key any, items any) (any, error) {
if key == nil {
return nil, errors.New("nil is not a valid key to group by")
}
if g, ok := items.(collections.Grouper); ok {
return g.Group(key, items)
}
in := newSliceElement(items)
if g, ok := in.(collections.Grouper); ok {
return g.Group(key, items)
}
return nil, fmt.Errorf("grouping not supported for type %T %T", items, in)
}
// IsSet returns whether a given array, channel, slice, or map in c has the given key
// defined.
func (ns *Namespace) IsSet(c any, key any) (bool, error) {
av := reflect.ValueOf(c)
kv := reflect.ValueOf(key)
switch av.Kind() {
case reflect.Array, reflect.Chan, reflect.Slice:
k, err := cast.ToIntE(key)
if err != nil {
return false, fmt.Errorf("isset unable to use key of type %T as index", key)
}
if av.Len() > k {
return true, nil
}
case reflect.Map:View on GitHub (pinned to 52c9bd7908)