{"record":{"id":"21cd9288457dc926","repo":"gohugoio/hugo","slug":"can-t-iterate-over-a-nil-value-of-type-type","errorCode":null,"errorMessage":"can't iterate over a nil value of type {type}","messagePattern":"can't iterate over a nil value of type (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/collections/where.go","lineNumber":33,"sourceCode":"\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\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/common/hstrings\"\n\t\"github.com/gohugoio/hugo/compare\"\n)\n\n// Where returns a filtered subset of collection c.\nfunc (ns *Namespace) Where(ctx context.Context, c, key any, args ...any) (any, error) {\n\tseqv, isNil := hreflect.Indirect(reflect.ValueOf(c))\n\tif isNil {\n\t\treturn nil, errors.New(\"can't iterate over a nil value of type \" + reflect.ValueOf(c).Type().String())\n\t}\n\n\tmv, op, err := parseWhereArgs(args...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tctxv := reflect.ValueOf(ctx)\n\n\tvar path []string\n\tkv := reflect.ValueOf(key)\n\tif kv.Kind() == reflect.String {\n\t\tpath = strings.Split(strings.Trim(kv.String(), \".\"), \".\")\n\t}\n\n\tswitch seqv.Kind() {\n\tcase reflect.Array, reflect.Slice:\n\t\treturn ns.checkWhereArray(ctxv, seqv, kv, mv, path, op)","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/collections/where.go#L15-L51","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Guard with `{{ with $pages }}{{ where . \"Section\" \"blog\" }}{{ end }}`.","Default to an empty slice: `{{ $pages = $pages | default slice }}`.","Fix upstream code to return an empty (non-nil) slice instead of a nil pointer."],"exampleFix":"// before\n{{ where $maybeNil \"Section\" \"blog\" }}\n// after\n{{ with $maybeNil }}{{ where . \"Section\" \"blog\" }}{{ else }}{{ slice }}{{ end }}","handlingStrategy":"validation","validationCode":"{{ with $pages }}{{ where . \"Section\" \"blog\" }}{{ else }}{{ slice }}{{ end }}","typeGuard":"func isNonNilCollection(v any) bool {\n    if v == nil { return false }\n    rv := reflect.ValueOf(v)\n    if rv.Kind() == reflect.Pointer && rv.IsNil() { return false }\n    kind := rv.Kind()\n    return kind == reflect.Slice || kind == reflect.Array || kind == reflect.Map\n}","tryCatchPattern":null,"preventionTips":["Guard `where` input with `{{ with }}`.","Default collections to empty slices upstream.","Prefer returning `[]T{}` over `nil` from Go code."],"tags":["hugo","template","collections","where","nil-pointer"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}