gohugoio/hugo · error
slice of nil pointer
Error message
slice of nil pointer
What it means
Raised by the `slice` action when the argument is a pointer that is non-nil in interface but points to nothing — `indirect` returns isNil=true at funcs.go:248-249. The template engine dereferences pointers automatically, but a nil `*[]T` or `*string` cannot be sliced because there is no underlying value.
Source
Thrown at tpl/internal/go_templates/texttemplate/funcs.go:249
}
}
return item, nil
}
// Slicing.
// slice returns the result of slicing its first argument by the remaining
// arguments. Thus "slice x 1 2" is, in Go syntax, x[1:2], while "slice x"
// is x[:], "slice x 1" is x[1:], and "slice x 1 2 3" is x[1:2:3]. The first
// argument must be a string, slice, or array.
func slice(item reflect.Value, indexes ...reflect.Value) (reflect.Value, error) {
item = indirectInterface(item)
if !item.IsValid() {
return reflect.Value{}, fmt.Errorf("slice of untyped nil")
}
var isNil bool
if item, isNil = indirect(item); isNil {
return reflect.Value{}, fmt.Errorf("slice of nil pointer")
}
if len(indexes) > 3 {
return reflect.Value{}, fmt.Errorf("too many slice indexes: %d", len(indexes))
}
var cap int
switch item.Kind() {
case reflect.String:
if len(indexes) == 3 {
return reflect.Value{}, fmt.Errorf("cannot 3-index slice a string")
}
cap = item.Len()
case reflect.Array, reflect.Slice:
cap = item.Cap()
default:
return reflect.Value{}, fmt.Errorf("can't slice item of type %s", item.Type())
}
// set default values for cases item[:], item[i:].
idx := [3]int{0, item.Len()}View on GitHub (pinned to 52c9bd7908)
Solutions
- Initialize the pointer in Go before passing it to the template, or change the field from `*[]T`/`*string` to a value type.
- Guard in the template: `{{with .Ptr}}{{slice . 0 1}}{{end}}` — `with` treats a nil pointer as false.
- Return a non-nil zero value (empty slice/string) from the data layer instead of a nil pointer.
Example fix
// before (Go)
type Data struct{ Items *[]string }
// template
{{slice .Items 0 5}} // .Items is nil pointer -> error
// after
{{with .Items}}{{slice . 0 5}}{{end}} Defensive patterns
Strategy: validation
Validate before calling
// In template:
// {{with .Ptr}}{{slice . 0 1}}{{end}}
// In Go, initialize pointer fields before rendering:
// if d.Items == nil { d.Items = &[]string{} } Type guard
func nonNilPointer(v interface{}) bool {
rv := reflect.ValueOf(v)
return rv.IsValid() && rv.Kind() == reflect.Ptr && !rv.IsNil()
} Prevention
- Prefer value types over pointer types for fields rendered in templates.
- Initialize all pointer fields in the data constructor.
- Use {{with}} to guard optional pointer fields.
When it happens
Trigger: `{{slice .Ptr 0 1}}` where `.Ptr` is `*[]int` and is nil; passing a nil pointer to a slice builtin; a struct field typed `*string` that was never initialized.
Common situations: Go struct fields exposed to templates as pointer types for optional/omitempty semantics; JSON unmarshaling into pointer fields that were absent in the source; newer API returning pointer-to-slice where an older one returned slice directly.
Related errors
- slice of untyped nil
- too many slice indexes: %d
- cannot 3-index slice a string
- can't slice item of type %s
- invalid slice index: %d > %d
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/c53548f3ec78aa25.
Report an issue: GitHub.