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

  1. Guard with `{{ with $pages }}{{ where . "Section" "blog" }}{{ end }}`.
  2. Default to an empty slice: `{{ $pages = $pages | default slice }}`.
  3. 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

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


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/21cd9288457dc926. Report an issue: GitHub.