gohugoio/hugo · error
can't iterate over a nil value
Error message
can't iterate over a nil value
What it means
After the literal-nil check, collections.Sort dereferences the value with hreflect.Indirect; if the argument is a typed nil (e.g. a nil pointer, nil map, or nil slice behind an interface), Indirect reports isNil and this error is returned. It distinguishes 'you passed nothing' (error 172) from 'you passed a typed value that is nil under the hood'.
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 8a468df065)
Solutions
- Wrap in `with` so nil values are skipped: `{{ with $seq }}{{ sort . }}{{ end }}`.
- Check the producing call — e.g. verify `.Site.GetPage "..."` actually finds a page before sorting anything derived from it.
- Initialize the collection (e.g. `slice` or `dict`) before conditionally appending, so it is never a typed nil.
Example fix
<!-- before -->
{{ $p := .Site.GetPage "/missing" }}
{{ sort $p.Pages }}
<!-- after -->
{{ with .Site.GetPage "/missing" }}{{ sort .Pages }}{{ end }} Defensive patterns
Strategy: validation
Validate before calling
{{ $items := site.Data.products }}
{{ with $items }}{{ range sort . "name" }}...{{ end }}{{ end }} Type guard
{{ if ne $items nil }}{{ sort $items }}{{ end }} Try / catch
{{ with try (sort site.Data.maybe) }}{{ if .Err }}{{ warnf "nothing to sort: %s" .Err }}{{ end }}{{ end }} Prevention
- Missing data files and unset params yield nil — use `with` to skip the whole block
- Use `default slice` to substitute an empty slice: `sort (.Params.tags | default slice)`
- Check `isset` for map keys before sorting their values
When it happens
Trigger: Passing a nil pointer or nil-valued typed variable to `sort` — e.g. `{{ sort $p }}` where `$p` is a nil `*Page` or a nil map returned from a partial/function, or sorting a dereferenced pointer field that was never initialized.
Common situations: Sorting the result of `.GetPage` when the page doesn't exist (returns nil pointer); sorting data from `getJSON`/`resources` calls that failed and returned typed nil; passing scratch/store values that were set to a typed nil earlier in the template.
Related errors
- sequence must be provided
- both limit and seq must be provided
- nil is not a valid key to group by
- cannot append slice of %s to slice of %s
- symdiff: failed to convert value: %w
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/22dd48111ac3f851.json.
Report an issue: GitHub ↗.