gohugoio/hugo · error
index of type %T with args %v failed: %s
Error message
index of type %T with args %v failed: %s
What it means
This is the wrapper error for Hugo's `index` template function: any failure inside `doIndex` (unusable index type, unassignable map key, non-indexable value) is wrapped with the item's type and the arguments used. The underlying cause is in the trailing `%s`. Note that nil items and out-of-range indices deliberately return nil rather than erroring.
Source
Thrown at tpl/collections/index.go:37
"reflect"
"github.com/spf13/cast"
"github.com/gohugoio/hugo/common/hmaps"
"github.com/gohugoio/hugo/common/hreflect"
)
// Index returns the result of indexing its first argument by the following
// arguments. Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each
// indexed item must be a map, slice, or array.
//
// Adapted from Go stdlib src/text/template/funcs.go.
//
// We deviate from the stdlib mostly because of https://github.com/golang/go/issues/14751.
func (ns *Namespace) Index(item any, args ...any) (any, error) {
v, err := ns.doIndex(item, args...)
if err != nil {
return nil, fmt.Errorf("index of type %T with args %v failed: %s", item, args, err)
}
return v, nil
}
func (ns *Namespace) doIndex(item any, args ...any) (any, error) {
// TODO(moorereason): merge upstream changes.
v := reflect.ValueOf(item)
if !v.IsValid() {
// See issue 10489
// This used to be an error.
return nil, nil
}
var indices []any
if len(args) == 1 {
v := reflect.ValueOf(args[0])
if v.Kind() == reflect.Slice {View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Read the wrapped cause at the end of the message — it names the exact incompatibility.
- Check the item type with `printf "%T"` and pass an index of the matching type (use `int` to convert string digits: `index $list (int $i)`).
- For nested access into params/data, prefer dotted access or `index` with string keys only on maps.
- Guard optional lookups with `with`/`isset` before indexing.
Example fix
<!-- before -->
{{ index $slice "0" }}
<!-- after -->
{{ index $slice 0 }} Defensive patterns
Strategy: try-catch
Validate before calling
{{ if isset $collection $key }}{{ index $collection $key }}{{ end }} Type guard
{{ $indexable := or (reflect.IsMap $c) (reflect.IsSlice $c) }} Try / catch
{{ with try (index $collection $key) }}{{ with .Err }}{{ warnf "index failed: %s" . }}{{ else }}{{ .Value }}{{ end }}{{ end }} Prevention
- Use isset to test the key/position exists before indexing
- Ensure the key type matches the map's key type (string vs int)
- Guard against indexing scalars or nil returned from .Param lookups
When it happens
Trigger: `{{ index $item $key ... }}` where the key type is incompatible: indexing a slice with a string or float, indexing a map whose key type doesn't match the given key, or indexing a scalar (int, bool) that can't be indexed at all. Nested indexing like `index $x 1 "a"` fails at whichever level mismatches.
Common situations: Indexing a slice with a string from `.Params` (`index $list "0"` instead of 0), indexing site data with the wrong key type, passing a page or string where a map was expected, misusing `index` after `split`/`where` chains.
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/6ccbd92065fec36f.json.
Report an issue: GitHub ↗.