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

  1. 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).
  2. Fix the front matter or data file so the value is a list, or guard with {{ with .Params.items }}{{ where . ... }}{{ end }}.
  3. 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

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


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/5f4ebbec44dcd31a.json. Report an issue: GitHub ↗.