{"id":"5f4ebbec44dcd31a","repo":"gohugoio/hugo","slug":"can-t-iterate-over-t","errorCode":null,"errorMessage":"can't iterate over %T","messagePattern":"can't iterate over %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/collections/where.go","lineNumber":55,"sourceCode":"\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)\n\tcase reflect.Map:\n\t\treturn ns.checkWhereMap(ctxv, seqv, kv, mv, path, op)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"can't iterate over %T\", c)\n\t}\n}\n\nfunc (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error) {\n\tv, vIsNil := hreflect.Indirect(v)\n\tif !v.IsValid() {\n\t\tvIsNil = true\n\t}\n\n\tmv, mvIsNil := hreflect.Indirect(mv)\n\tif !mv.IsValid() {\n\t\tmvIsNil = true\n\t}\n\tif vIsNil || mvIsNil {\n\t\tswitch op {\n\t\tcase \"\", \"=\", \"==\", \"eq\":\n\t\t\treturn vIsNil == mvIsNil, nil\n\t\tcase \"!=\", \"<>\", \"ne\":","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/tpl/collections/where.go#L37-L73","documentation":"collections.Where (the where template function) can only filter arrays, slices, and maps. If the collection argument reflects to any other kind — a string, number, nil, or a single struct/Page rather than a Pages collection — Hugo reports it cannot iterate over that Go type (%T shows the concrete type).","triggerScenarios":"First argument to where is not a slice/array/map: {{ where .Params.foo \"k\" \"v\" }} where foo is a string or missing (nil), {{ where .Site \"...\" }} instead of .Site.Pages, or chaining where after a function that returned a single element (e.g. index).","commonSituations":"Front-matter param expected to be a list is authored as a scalar; .Params key typo yields nil; passing a Page instead of Pages; data file shape changed from array to object of a different kind after edits.","solutions":["Check the actual type of the first argument with {{ printf \"%T\" $x }} and pass a Pages/slice/map value (e.g. .Site.RegularPages, .Params.items).","Fix the front matter or data file so the value is a list, or guard with {{ with .Params.items }}{{ where . ... }}{{ end }}.","If chaining, ensure the upstream function (first, index, etc.) still returns a collection."],"exampleFix":"{{/* before */}}\n{{ range where .Params.author \"name\" \"jane\" }}...{{ end }}\n\n{{/* after — authors is a list in front matter */}}\n{{ range where .Params.authors \"name\" \"jane\" }}...{{ end }}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"{{/* Only pass slices/maps/pages to where */}}\n{{ $c := .Site.Params.items }}\n{{ if reflect.IsSlice $c | or (reflect.IsMap $c) }}\n  {{ $r := where $c \"enabled\" true }}\n{{ else }}\n  {{ errorf \"expected a collection, got %T\" $c }}\n{{ end }}","tryCatchPattern":null,"preventionTips":["Check reflect.IsSlice / reflect.IsMap before piping params into where/sort/range helpers","Remember a single map entry from config is not a slice — wrap with `slice` if needed","Don't pass nil or scalar site params into collection functions"],"tags":["hugo","templates","where","collections","type-error"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}