gohugoio/hugo · error
cannot index slice/array with type %s
Error message
cannot index slice/array with type %s
What it means
Returned by indexArg when the index value is valid but not an integer or unsigned-integer kind (e.g. a string, struct, float, bool). Slice/array/string indexing requires an integer index; non-integer types are rejected. The %s is the index value's type.
Source
Thrown at tpl/internal/go_templates/texttemplate/funcs.go:185
return true
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return true
}
return false
}
// indexArg checks if a reflect.Value can be used as an index, and converts it to int if possible.
func indexArg(index reflect.Value, cap int) (int, error) {
var x int64
switch index.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
x = index.Int()
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
x = int64(index.Uint())
case reflect.Invalid:
return 0, fmt.Errorf("cannot index slice/array with nil")
default:
return 0, fmt.Errorf("cannot index slice/array with type %s", index.Type())
}
if x < 0 || int(x) < 0 || int(x) > cap {
return 0, fmt.Errorf("index out of range: %d", x)
}
return int(x), nil
}
// Indexing.
// 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.
func index(item reflect.Value, indexes ...reflect.Value) (reflect.Value, error) {
item = indirectInterface(item)
if !item.IsValid() {
return reflect.Value{}, fmt.Errorf("index of untyped nil")
}
for _, index := range indexes {View on GitHub (pinned to 52c9bd7908)
Solutions
- Convert the index to an integer in the template via a helper func before indexing.
- Prepare indices as ints in the data layer (strconv.Atoi) before render.
- Use map access ({{.Map.key}}) instead of index when the key is non-numeric.
- Add a typed accessor func that does the conversion safely.
Example fix
// before
{{index .Items .Pos}} // .Pos is string "3"
// after
// register "atoi": func(s string) (int, error)
{{$i := atoi .Pos}}
{{index .Items $i}} Defensive patterns
Strategy: type-guard
Validate before calling
// register "atoi" and use it before indexing
template.Funcs(template.FuncMap{
"atoi": func(s string) (int, error) { return strconv.Atoi(s) },
})
// template: {{$i := atoi .Pos}}{{index .Items $i}} Type guard
func isNumericIndex(i any) bool {
if i == nil { return false }
switch reflect.TypeOf(i).Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return true
}
return false
} Prevention
- Convert string params to int (strconv.Atoi) before indexing.
- Use map access for non-numeric keys instead of index.
- Keep collection indexing strictly integer-typed in the data model.
When it happens
Trigger: Calling {{index .Slice .Name}} where .Name is a string; passing a float or struct as an index; indexing with a map-derived key of the wrong kind.
Common situations: URL params arriving as strings used directly as indices; a field that holds an identifier string mistaken for a numeric position; mixing map-style and slice-style indexing.
Related errors
- value has type %s; should be %s
- cannot index slice/array with nil
- index of untyped nil
- index of nil pointer
- invalid function signature for %s: second return value shoul
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/7dbcb6dbfc3ac316.
Report an issue: GitHub.