gohugoio/hugo · error
nil is not a valid key to group by
Error message
nil is not a valid key to group by
What it means
Thrown by the Group template function when its first argument (the group key) is nil. Grouping requires a concrete key to bucket items under, so a nil key is rejected outright before any collection is inspected. This is a hard precondition check at the very top of the function (line 313).
Solutions
- Default the key before grouping: {{ $key := .Params.category | default "uncategorized" }} {{ group $key .Pages }}.
- Guard with {{ with }} so the group call only runs when the key is non-nil: {{ with .Params.category }}{{ group . $.Pages }}{{ end }}.
- Audit content files and ensure the field used as the group key is present on every page in the set being grouped.
Example fix
// before
{{ group .Params.author .Pages }}
// after
{{ $author := .Params.author | default "unknown" }}
{{ group $author .Pages }} Defensive patterns
Strategy: validation
Validate before calling
{{ $key := .Params.category | default "uncategorized" }}
{{ if ne $key nil }}{{ group $key .Pages }}{{ end }} Prevention
- Always pipe group keys through | default before calling group.
- Audit content front matter to ensure the group-by field exists on all pages in the set.
- Use {{ with $key }} around the group call so nil keys are skipped.
When it happens
Trigger: Calling {{ group $key .Pages }} or ns.Group(key, items) in Go where key evaluates to nil (e.g. an unset page param, a missing front matter field, or a template variable never assigned). Also hit when a derived grouping key like .Date is nil on a draft/fixture page.
Common situations: Grouping pages by a front matter field (e.g. tags, categories, author) that is omitted on some content; using {{ .Param "x" }} that returns nil; content fixtures in tests missing the field the layout groups on; upgrading layouts that assume a field always exists.
Related errors
- both count and seq must be provided
- cannot index slice/array with nil
- sequence must be provided
- argument must be a slice
- arguments must be slices or arrays
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/f76b0e41521862a8.
Report an issue: GitHub.
Appendix: source
Thrown at tpl/collections/collections.go:314
}
ins.handleValuePair(l1vv, l2vv)
}
}
return ins.r.Interface(), nil
default:
return nil, errors.New("can't iterate over " + reflect.ValueOf(l2).Type().String())
}
default:
return nil, errors.New("can't iterate over " + reflect.ValueOf(l1).Type().String())
}
}
// 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) {View on GitHub (pinned to 52c9bd7908)