gohugoio/hugo · error

can't iterate over a nil value

Error message

can't iterate over a nil value

What it means

Apply (apply.go:36-40) passes c through reflect + hreflect.Indirect; if that yields a typed-nil pointer/slice (isNil==true) it bails. Literal nil is handled earlier at lines 28-30 (returns empty slice), so this path specifically means a non-nil interface wrapping a nil pointer.

Solutions

  1. Guard with {{ with $items }}{{ apply . "fn" }}{{ end }}
  2. Coalesce to an empty slice: {{ apply (default $items slice) "fn" }}
  3. Check {{ if $items }} before calling apply

Example fix

// before
{{ apply $maybeNil "upper" }}
// after
{{ with $maybeNil }}{{ apply . "upper" }}{{ end }}
Defensive patterns

Strategy: validation

Validate before calling

{{ with $items }}
  {{ apply . "upper" }}
{{ end }}

Type guard

{{/* non-empty typed guard: with skips typed-nil and zero values */}}
{{ with $items }}...{{ end }}

Prevention

When it happens

Trigger: Passing a *Pages, *[]Page, or nil map typed as a concrete pointer type to apply, where the underlying value is nil but the interface is non-nil.

Common situations: A page-collection variable declared but never assigned; frontmatter param that resolves to a nil pointer; .Next/.Prev on the last/first page returning a typed-nil Page.

Related errors


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

Appendix: source

Thrown at tpl/collections/apply.go:39

	"strings"

	"github.com/gohugoio/hugo/common/hreflect"
)

// Apply takes an array or slice c and returns a new slice with the function fname applied over it.
func (ns *Namespace) Apply(ctx context.Context, c any, fname string, args ...any) (any, error) {
	if c == nil {
		return make([]any, 0), nil
	}

	if fname == "apply" {
		return nil, errors.New("can't apply myself (no turtles allowed)")
	}

	seqv := reflect.ValueOf(c)
	seqv, isNil := hreflect.Indirect(seqv)
	if isNil {
		return nil, errors.New("can't iterate over a nil value")
	}

	fnv, found := ns.lookupFunc(ctx, fname)
	if !found {
		return nil, errors.New("can't find function " + fname)
	}

	switch seqv.Kind() {
	case reflect.Array, reflect.Slice:
		r := make([]any, seqv.Len())
		for i := range seqv.Len() {
			vv := seqv.Index(i)

			vvv, err := applyFnToThis(ctx, fnv, vv, args...)
			if err != nil {
				return nil, err
			}

View on GitHub (pinned to 52c9bd7908)