{"record":{"id":"22dd48111ac3f851","repo":"gohugoio/hugo","slug":"can-t-iterate-over-a-nil-value-22dd48","errorCode":null,"errorMessage":"can't iterate over a nil value","messagePattern":"can't iterate over a nil value","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/collections/sort.go","lineNumber":38,"sourceCode":"\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/gohugoio/hugo/common/hmaps\"\n\t\"github.com/gohugoio/hugo/common/hreflect\"\n\t\"github.com/gohugoio/hugo/langs\"\n\t\"github.com/gohugoio/hugo/tpl/compare\"\n\t\"github.com/spf13/cast\"\n)\n\n// Sort returns a sorted copy of the list l.\nfunc (ns *Namespace) Sort(ctx context.Context, l any, args ...any) (any, error) {\n\tif l == nil {\n\t\treturn nil, errors.New(\"sequence must be provided\")\n\t}\n\n\tseqv, isNil := hreflect.Indirect(reflect.ValueOf(l))\n\tif isNil {\n\t\treturn nil, errors.New(\"can't iterate over a nil value\")\n\t}\n\n\tctxv := reflect.ValueOf(ctx)\n\n\tvar sliceType reflect.Type\n\tswitch seqv.Kind() {\n\tcase reflect.Array, reflect.Slice:\n\t\tsliceType = seqv.Type()\n\tcase reflect.Map:\n\t\tsliceType = reflect.SliceOf(seqv.Type().Elem())\n\tdefault:\n\t\treturn nil, errors.New(\"can't sort \" + reflect.ValueOf(l).Type().String())\n\t}\n\n\tcollator := langs.GetCollator1(ns.deps.Conf.Language().(*langs.Language))\n\n\t// Create a list of pairs that will be used to do the sort\n\tp := pairList{Collator: collator, sortComp: ns.sortComp, SortAsc: true, SliceType: sliceType}","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/collections/sort.go#L20-L56","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Guard with `{{ with $val }}{{ sort . }}{{ end }}` to skip nil entirely.","Initialize the variable to a concrete empty slice instead of a nil pointer upstream.","Use `default slice` to coerce to an empty collection before sorting."],"exampleFix":"// before\n{{ sort $maybeTypedNil }}\n// after\n{{ with $maybeTypedNil }}{{ sort . }}{{ else }}{{ slice }}{{ end }}","handlingStrategy":"validation","validationCode":"{{ with $maybeTypedNil }}{{ sort . }}{{ else }}{{ slice }}{{ end }}","typeGuard":"func isNonNilPointerDeref(v any) bool {\n    rv := reflect.ValueOf(v)\n    if rv.Kind() == reflect.Pointer && rv.IsNil() { return false }\n    return true\n}","tryCatchPattern":null,"preventionTips":["Use `{{ with }}` to skip nil pointers before sort.","Ensure upstream code returns empty (non-nil) slices.","Coerce with `| default slice`."],"tags":["hugo","template","collections","sort","nil-pointer"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}