gohugoio/hugo · error

can't iterate over a nil value

Error message

can't iterate over a nil value

What it means

The `sort` function uses `hreflect.Indirect` to dereference the input. If the value is a typed nil pointer (e.g. `(*[]Page)(nil)`), `Indirect` reports `isNil == true` and this error fires. This is distinct from error 123 which catches the untyped `nil` interface.

Source

Thrown at tpl/collections/sort.go:38

	"sort"
	"strings"

	"github.com/gohugoio/hugo/common/hmaps"
	"github.com/gohugoio/hugo/common/hreflect"
	"github.com/gohugoio/hugo/langs"
	"github.com/gohugoio/hugo/tpl/compare"
	"github.com/spf13/cast"
)

// Sort returns a sorted copy of the list l.
func (ns *Namespace) Sort(ctx context.Context, l any, args ...any) (any, error) {
	if l == nil {
		return nil, errors.New("sequence must be provided")
	}

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

	ctxv := reflect.ValueOf(ctx)

	var sliceType reflect.Type
	switch seqv.Kind() {
	case reflect.Array, reflect.Slice:
		sliceType = seqv.Type()
	case reflect.Map:
		sliceType = reflect.SliceOf(seqv.Type().Elem())
	default:
		return nil, errors.New("can't sort " + reflect.ValueOf(l).Type().String())
	}

	collator := langs.GetCollator1(ns.deps.Conf.Language().(*langs.Language))

	// Create a list of pairs that will be used to do the sort
	p := pairList{Collator: collator, sortComp: ns.sortComp, SortAsc: true, SliceType: sliceType}

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Guard with `{{ with $val }}{{ sort . }}{{ end }}` to skip nil entirely.
  2. Initialize the variable to a concrete empty slice instead of a nil pointer upstream.
  3. Use `default slice` to coerce to an empty collection before sorting.

Example fix

// before
{{ sort $maybeTypedNil }}
// after
{{ with $maybeTypedNil }}{{ sort . }}{{ else }}{{ slice }}{{ end }}
Defensive patterns

Strategy: validation

Validate before calling

{{ with $maybeTypedNil }}{{ sort . }}{{ else }}{{ slice }}{{ end }}

Type guard

func isNonNilPointerDeref(v any) bool {
    rv := reflect.ValueOf(v)
    if rv.Kind() == reflect.Pointer && rv.IsNil() { return false }
    return true
}

Prevention

When it happens

Trigger: Passing a typed nil pointer to sort, e.g. a variable declared as `*[]string` that was never initialized: `{{ sort $typedNilPtr }}`. The check fires at sort.go:37–38.

Common situations: A Go-backed template variable or a Scratch value holds a typed nil pointer after a failed lookup. The developer sees a non-nil interface but the underlying pointer is nil.

Related errors


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