gohugoio/hugo · error
cannot index slice/array with nil
Error message
cannot index slice/array with nil
What it means
Inside `index`, when the indexed value is a slice, array, or string, the index must be an integer. A nil index has reflect.Kind Invalid, which cannot be converted to an integer position, so Hugo rejects it explicitly. This surfaces wrapped inside the "index of type %T with args %v failed" error.
Source
Thrown at tpl/collections/index.go:88
for _, i := range indices {
index := reflect.ValueOf(i)
var isNil bool
if v, isNil = hreflect.Indirect(v); isNil {
// See issue 10489
// This used to be an error.
return nil, nil
}
switch v.Kind() {
case reflect.Array, reflect.Slice, reflect.String:
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 nil, errors.New("cannot index slice/array with nil")
default:
return nil, fmt.Errorf("cannot index slice/array with type %s", index.Type())
}
if x < 0 || x >= int64(v.Len()) {
// We deviate from stdlib here. Don't return an error if the
// index is out of range.
return nil, nil
}
v = v.Index(int(x))
case reflect.Map:
index, err := prepareArg(index, v.Type().Key())
if err != nil {
return nil, err
}
if x := v.MapIndex(index); x.IsValid() {
v = x
} else {View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Provide a default for the index: `{{ index $slice (default 0 $i) }}`.
- Guard the lookup: `{{ with $i }}{{ index $slice . }}{{ end }}`.
- Trace where the nil comes from (unset param, missing shortcode attribute) and fix the source data.
Example fix
<!-- before -->
{{ index $items (.Get "n") }}
<!-- after -->
{{ index $items (default 0 (.Get "n")) }} Defensive patterns
Strategy: validation
Validate before calling
{{ if ne $key nil }}{{ index $slice $key }}{{ end }} Type guard
{{ $validKey := and (ne $key nil) (ge $key 0) (lt $key (len $slice)) }} Try / catch
{{ with try (index $slice $key) }}{{ with .Err }}{{ warnf "slice index failed: %s" . }}{{ end }}{{ end }} Prevention
- Never pass a possibly-nil variable as a slice index — default it with `| default 0`
- Slices need integer keys; nil keys only make sense for maps, and not here
- Bounds-check with len before indexing user-derived positions
When it happens
Trigger: `{{ index $slice $i }}` where `$i` is nil — typically an unset variable, a missing `.Params` key, or a shortcode `.Get` that returned nothing. Only occurs when the container is a slice/array/string; nil keys on maps take a different path.
Common situations: Shortcodes using `index $args (.Get "pos")` when the attribute is omitted; templates reading an index from front matter that some pages don't define; loop variables shadowed or out of scope.
Related errors
- sequence must be provided
- can't iterate over a nil value
- index of type %T with args %v failed: %s
- both limit and seq must be provided
- nil is not a valid key to group by
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/d617550af6c872a3.json.
Report an issue: GitHub ↗.