gohugoio/hugo · error
can't iterate over a nil value of type {type}
Error message
can't iterate over a nil value of type {type} What it means
The `where` function filters a collection by a key and optional operator/match value. If the collection argument, after `hreflect.Indirect`, is a typed nil pointer, this error fires with the concrete type name. It is the `where` analogue of the typed-nil sort error (124).
Source
Thrown at tpl/collections/where.go:33
import (
"context"
"errors"
"fmt"
"reflect"
"strings"
"github.com/gohugoio/hugo/common/hmaps"
"github.com/gohugoio/hugo/common/hreflect"
"github.com/gohugoio/hugo/common/hstrings"
"github.com/gohugoio/hugo/compare"
)
// Where returns a filtered subset of collection c.
func (ns *Namespace) Where(ctx context.Context, c, key any, args ...any) (any, error) {
seqv, isNil := hreflect.Indirect(reflect.ValueOf(c))
if isNil {
return nil, errors.New("can't iterate over a nil value of type " + reflect.ValueOf(c).Type().String())
}
mv, op, err := parseWhereArgs(args...)
if err != nil {
return nil, err
}
ctxv := reflect.ValueOf(ctx)
var path []string
kv := reflect.ValueOf(key)
if kv.Kind() == reflect.String {
path = strings.Split(strings.Trim(kv.String(), "."), ".")
}
switch seqv.Kind() {
case reflect.Array, reflect.Slice:
return ns.checkWhereArray(ctxv, seqv, kv, mv, path, op)View on GitHub (pinned to 52c9bd7908)
Solutions
- Guard with `{{ with $pages }}{{ where . "Section" "blog" }}{{ end }}`.
- Default to an empty slice: `{{ $pages = $pages | default slice }}`.
- Fix upstream code to return an empty (non-nil) slice instead of a nil pointer.
Example fix
// before
{{ where $maybeNil "Section" "blog" }}
// after
{{ with $maybeNil }}{{ where . "Section" "blog" }}{{ else }}{{ slice }}{{ end }} Defensive patterns
Strategy: validation
Validate before calling
{{ with $pages }}{{ where . "Section" "blog" }}{{ else }}{{ slice }}{{ end }} Type guard
func isNonNilCollection(v any) bool {
if v == nil { return false }
rv := reflect.ValueOf(v)
if rv.Kind() == reflect.Pointer && rv.IsNil() { return false }
kind := rv.Kind()
return kind == reflect.Slice || kind == reflect.Array || kind == reflect.Map
} Prevention
- Guard `where` input with `{{ with }}`.
- Default collections to empty slices upstream.
- Prefer returning `[]T{}` over `nil` from Go code.
When it happens
Trigger: Calling `{{ where $typedNilPtr "Section" "blog" }}` where `$typedNilPtr` is a `*[]Page(nil)` or similar typed nil. The check at where.go:31–33 fires when `isNil` is true after dereferencing.
Common situations: A `.Scratch.Get` or page method returns a typed nil pointer when no results exist, and the template passes it directly to `where` expecting an empty result rather than an error.
Related errors
- can't iterate over a nil value
- invalid intersect values
- no such operator
- can't evaluate an invalid value
- operator argument must be string type
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/21cd9288457dc926.
Report an issue: GitHub.