{"id":"631a3770cdeefea2","repo":"gohugoio/hugo","slug":"isset-unable-to-use-key-of-type-t-as-index","errorCode":null,"errorMessage":"isset unable to use key of type %T as index","messagePattern":"isset unable to use key of type %T as index","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/collections/collections.go","lineNumber":340,"sourceCode":"\n\tif g, ok := in.(collections.Grouper); ok {\n\t\treturn g.Group(key, items)\n\t}\n\n\treturn nil, fmt.Errorf(\"grouping not supported for type %T %T\", items, in)\n}\n\n// IsSet returns whether a given array, channel, slice, or map in c has the given key\n// defined.\nfunc (ns *Namespace) IsSet(c any, key any) (bool, error) {\n\tav := reflect.ValueOf(c)\n\tkv := reflect.ValueOf(key)\n\n\tswitch av.Kind() {\n\tcase reflect.Array, reflect.Chan, reflect.Slice:\n\t\tk, err := cast.ToIntE(key)\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"isset unable to use key of type %T as index\", key)\n\t\t}\n\t\tif av.Len() > k {\n\t\t\treturn true, nil\n\t\t}\n\tcase reflect.Map:\n\t\tif kv.Type() == av.Type().Key() {\n\t\t\treturn av.MapIndex(kv).IsValid(), nil\n\t\t}\n\tdefault:\n\t\tns.deps.Log.Warnf(\"calling IsSet with unsupported type %q (%T) for key %v will always return false.\\n\", av.Kind(), c, key)\n\t}\n\n\treturn false, nil\n}\n\n// Last returns the last limit items in the list l.\nfunc (ns *Namespace) Last(limit any, l any) (any, error) {\n\tif limit == nil || l == nil {","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/tpl/collections/collections.go#L322-L358","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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 }}`."],"exampleFix":"<!-- before -->\n{{ if isset .Params.tags \"news\" }}...{{ end }}\n<!-- after: tags is a slice; use `in` for membership -->\n{{ if in .Params.tags \"news\" }}...{{ end }}","handlingStrategy":"type-guard","validationCode":"{{/* ensure key is a scalar (string/int), not a slice or map */}}\n{{ if or (reflect.IsSlice $key) (reflect.IsMap $key) }}\n  {{ errorf \"key must be a string or integer, got %T\" $key }}\n{{ end }}\n{{ if isset $collection $key }}{{ index $collection $key }}{{ end }}","typeGuard":"{{/* narrow: strings index maps, ints index slices */}}\n{{ $ok := or (eq (printf \"%T\" $key) \"string\") (eq (printf \"%T\" $key) \"int\") }}","tryCatchPattern":null,"preventionTips":["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."],"tags":["hugo","templates","isset","type-mismatch"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}