gohugoio/hugo · error
isset unable to use key of type %T as index
Error message
isset unable to use key of type %T as index
What it means
Hugo's `isset` template function checks whether an index/key exists in a collection. When the collection is an array, slice, or channel, the key must be castable to an integer index; this error is returned when `cast.ToIntE` fails on the supplied key, e.g. a non-numeric string used against a slice.
Source
Thrown at tpl/collections/collections.go:340
if g, ok := in.(collections.Grouper); ok {
return g.Group(key, items)
}
return nil, fmt.Errorf("grouping not supported for type %T %T", items, in)
}
// IsSet returns whether a given array, channel, slice, or map in c has the given key
// defined.
func (ns *Namespace) IsSet(c any, key any) (bool, error) {
av := reflect.ValueOf(c)
kv := reflect.ValueOf(key)
switch av.Kind() {
case reflect.Array, reflect.Chan, reflect.Slice:
k, err := cast.ToIntE(key)
if err != nil {
return false, fmt.Errorf("isset unable to use key of type %T as index", key)
}
if av.Len() > k {
return true, nil
}
case reflect.Map:
if kv.Type() == av.Type().Key() {
return av.MapIndex(kv).IsValid(), nil
}
default:
ns.deps.Log.Warnf("calling IsSet with unsupported type %q (%T) for key %v will always return false.\n", av.Kind(), c, key)
}
return false, nil
}
// Last returns the last limit items in the list l.
func (ns *Namespace) Last(limit any, l any) (any, error) {
if limit == nil || l == nil {View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Pass an integer index when the first argument is a slice/array: `{{ isset $slice 0 }}`.
- If you meant to check a map key, verify the value actually is a map (`printf "%T"` it) — front matter lists vs maps are easy to confuse.
- Guard with a kind check: `{{ if reflect.IsMap $c }}{{ isset $c "key" }}{{ end }}`.
Example fix
<!-- before -->
{{ if isset .Params.tags "news" }}...{{ end }}
<!-- after: tags is a slice; use `in` for membership -->
{{ if in .Params.tags "news" }}...{{ end }} Defensive patterns
Strategy: type-guard
Validate before calling
{{/* ensure key is a scalar (string/int), not a slice or map */}}
{{ if or (reflect.IsSlice $key) (reflect.IsMap $key) }}
{{ errorf "key must be a string or integer, got %T" $key }}
{{ end }}
{{ if isset $collection $key }}{{ index $collection $key }}{{ end }} Type guard
{{/* narrow: strings index maps, ints index slices */}}
{{ $ok := or (eq (printf "%T" $key) "string") (eq (printf "%T" $key) "int") }} Prevention
- Use string keys with maps and integer keys with slices/arrays when calling isset.
- Don't pass the result of a range over a map (which yields values, possibly complex) as an isset key.
- When the key comes from front matter or data files, coerce it explicitly with `string` or `int` before use.
When it happens
Trigger: Calling `{{ isset .Slice "foo" }}` or `{{ isset $arr .SomeStringVar }}` where the first argument is an array/slice/channel and the key cannot be converted to an int.
Common situations: Templates written for a map (e.g. `.Params`) later applied to a slice; iterating mixed data from front matter or data files where a field is sometimes a map and sometimes a list; passing a page or dict as the key by mistake.
Related errors
- arguments to complement must be slices or arrays
- %s isn't a key of map type %s
- %s is neither a struct field, a method nor a map element of
- type %T not supported in Resource transformations
- destination must be a map, got %T
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/631a3770cdeefea2.json.
Report an issue: GitHub ↗.