gohugoio/hugo · error
can't iterate over %T
Error message
can't iterate over %T
What it means
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).
Source
Thrown at tpl/collections/where.go:55
if err != nil {
return nil, err
}
ctxv := reflect.ValueOf(ctx)
var path []string
kv := reflect.ValueOf(key)
if kv.Kind() == reflect.String {
path = strings.Split(strings.Trim(kv.String(), "."), ".")
}
switch seqv.Kind() {
case reflect.Array, reflect.Slice:
return ns.checkWhereArray(ctxv, seqv, kv, mv, path, op)
case reflect.Map:
return ns.checkWhereMap(ctxv, seqv, kv, mv, path, op)
default:
return nil, fmt.Errorf("can't iterate over %T", c)
}
}
func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error) {
v, vIsNil := hreflect.Indirect(v)
if !v.IsValid() {
vIsNil = true
}
mv, mvIsNil := hreflect.Indirect(mv)
if !mv.IsValid() {
mvIsNil = true
}
if vIsNil || mvIsNil {
switch op {
case "", "=", "==", "eq":
return vIsNil == mvIsNil, nil
case "!=", "<>", "ne":View on GitHub ↗ (pinned to 8a468df065)
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.
Example fix
{{/* before */}}
{{ range where .Params.author "name" "jane" }}...{{ end }}
{{/* after — authors is a list in front matter */}}
{{ range where .Params.authors "name" "jane" }}...{{ end }} Defensive patterns
Strategy: type-guard
Type guard
{{/* Only pass slices/maps/pages to where */}}
{{ $c := .Site.Params.items }}
{{ if reflect.IsSlice $c | or (reflect.IsMap $c) }}
{{ $r := where $c "enabled" true }}
{{ else }}
{{ errorf "expected a collection, got %T" $c }}
{{ end }} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- arguments to symdiff must be slices or arrays
- invalid intersect values
- no such operator
- invalid dictionary key
- grouping not supported for type %T %T
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/5f4ebbec44dcd31a.json.
Report an issue: GitHub ↗.