gohugoio/hugo · error
can't iterate over {type}
Error message
can't iterate over {type} What it means
After (collections.go:85-90) accepts only reflect.Array, Slice, or String. Any other Kind (map, struct, int, etc.) reaches the default branch and reports the actual type.
Source
Thrown at tpl/collections/collections.go:89
if err != nil {
return nil, err
}
if nv < 0 {
return nil, errors.New("sequence bounds out of range [" + cast.ToString(nv) + ":]")
}
lv := reflect.ValueOf(l)
lv, isNil := hreflect.Indirect(lv)
if isNil {
return nil, errors.New("can't iterate over a nil value")
}
switch lv.Kind() {
case reflect.Array, reflect.Slice, reflect.String:
// okay
default:
return nil, errors.New("can't iterate over " + reflect.ValueOf(l).Type().String())
}
if nv >= lv.Len() {
return lv.Slice(0, 0).Interface(), nil
}
return lv.Slice(nv, lv.Len()).Interface(), nil
}
// Delimit takes a given list l and returns a string delimited by sep.
// If last is passed to the function, it will be used as the final delimiter.
func (ns *Namespace) Delimit(ctx context.Context, l, sep any, last ...any) (string, error) {
d, err := cast.ToStringE(sep)
if err != nil {
return "", err
}
var dLast *stringView on GitHub (pinned to 52c9bd7908)
Solutions
- Pass a slice/array/string, not a map or scalar
- If you have a map, extract a slice first (e.g. its values or a known sub-collection)
- Use .Pages instead of .Page for collections
Example fix
// before
{{ after 2 .Params }}
// after
{{ after 2 .Pages }} Defensive patterns
Strategy: type-guard
Validate before calling
{{ if reflect.IsSlice .Pages }}
{{ after 2 .Pages }}
{{ end }} Type guard
{{/* Go-side */}}
func isIteratable(v any) bool {
k := reflect.TypeOf(v).Kind()
return k == reflect.Slice || k == reflect.Array || k == reflect.String
} Prevention
- Pass only slices/arrays/strings to after
- Use .Pages (collection) not .Page (single)
- Convert maps to a sorted slice before slicing
When it happens
Trigger: {{ after 2 .Site.Data }} (map), {{ after 2 42 }} (int), {{ after 2 .Page }} (struct).
Common situations: Passing a dict/params map where a slice was expected; passing a single Page object instead of a page collection; passing a number.
Related errors
- called apply using {xt} as type {targ}
- invalid dictionary key
- intersect does not support slices or arrays of uncomparable
- need at least 2 arguments to append
- can't apply myself (no turtles allowed)
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/048d52dde38536d0.
Report an issue: GitHub.