gohugoio/hugo · error
cannot index slice/array with nil
Error message
cannot index slice/array with nil
What it means
Returned by indexArg when the index value provided to index a slice/array/string is reflect-invalid (untyped nil, e.g. an unset variable or an explicit nil). Indexing requires a concrete integer; nil is not coercible. This backs the index builtin and slice bounds checking.
Source
Thrown at tpl/internal/go_templates/texttemplate/funcs.go:183
switch typ {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
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")View on GitHub (pinned to 52c9bd7908)
Solutions
- Ensure the index expression yields a concrete int before calling index.
- Guard with {{if $i}}{{index .Slice $i}}{{end}} or default to 0: {{$i := or $i 0}}.
- Validate index is non-nil and numeric in the data layer before rendering.
- Provide explicit defaults for optional values feeding index.
Example fix
// before
{{index .Items .Selected}} // .Selected is nil -> error
// after
{{$idx := or .Selected 0}}
{{index .Items $idx}} Defensive patterns
Strategy: validation
Validate before calling
// register a nil-safe index helper
template.Funcs(template.FuncMap{
"at": func(seq any, i any) (any, error) {
if i == nil { return nil, fmt.Errorf("index is nil") }
return index(reflect.ValueOf(seq), reflect.ValueOf(i))
},
}) Type guard
func isIntegerIndex(i any) bool {
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, reflect.Uintptr:
return true
}
return false
} Prevention
- Default optional index values: {{$i := or .Selected 0}}.
- Register a nil-safe index helper used by templates.
- Validate indices are non-nil integers in the data layer.
When it happens
Trigger: Using {{index .Slice $i}} where $i is an unset variable or nil; {{index .Arr nil}}; a pipeline that produces no value being used as the index.
Common situations: A range variable not bound in an edge case; optional query params that are nil passed straight to index; refactoring that left a variable uninitialized.
Related errors
- index of untyped nil
- cannot index slice/array with type %s
- index of nil pointer
- value is nil; should be of type %s
- invalid function signature for %s: second return value shoul
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/ef1982d95be8b785.
Report an issue: GitHub.