gohugoio/hugo · error
slice bounds out of range
Error message
slice bounds out of range
What it means
Thrown by strings.SliceString when the start index is negative or greater than/equal to the rune length of the string. The check is argStart < 0 || argStart >= len(asRunes), operating on rune count (not byte count), so multibyte strings are handled correctly.
Solutions
- Clamp the start to the valid range: {{ $start = math.Min (float $start) (float (strings.RuneCount $s)) }} then cast to int.
- Use strings.Substr instead if you need negative indexing from the end.
- Guard with a length check before slicing.
Example fix
// before
{{ strings.SliceString $s $start }}
// after
{{ if lt $start (strings.RuneCount $s) }}{{ strings.SliceString $s $start }}{{ end }} Defensive patterns
Strategy: validation
Validate before calling
{{ $n := strings.RuneCount $s }}
{{ if and (ge $start 0) (lt $start $n) }}{{ strings.SliceString $s $start }}{{ end }} Prevention
- Validate the start index is within [0, runeCount) before slicing.
- Use strings.Substr if you need negative indexing.
- Remember bounds use rune count, not byte count.
When it happens
Trigger: Calling {{ strings.SliceString "abc" 5 }} (start beyond end), {{ strings.SliceString "abc" -1 }} (negative), or using a start index larger than the string's rune length.
Common situations: Indices computed from .Params that exceed string length on short strings; off-by-one errors; negative indices (SliceString does NOT support negative indexing, unlike Substr).
Related errors
- end argument must be integer
- start argument must be integer
- too few arguments
- too many arguments
- argument must be a slice
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/cb550488d4006ef6.
Report an issue: GitHub.
Appendix: source
Thrown at tpl/strings/strings.go:346
if argNum > 0 {
if argStart, err = cast.ToIntE(startEnd[0]); err != nil {
return "", errors.New("start argument must be integer")
}
}
if argNum > 1 {
if argEnd, err = cast.ToIntE(startEnd[1]); err != nil {
return "", errors.New("end argument must be integer")
}
}
if argNum > 2 {
return "", errors.New("too many arguments")
}
asRunes := []rune(aStr)
if argNum > 0 && (argStart < 0 || argStart >= len(asRunes)) {
return "", errors.New("slice bounds out of range")
}
if argNum == 2 {
if argEnd < 0 || argEnd > len(asRunes) {
return "", errors.New("slice bounds out of range")
}
return string(asRunes[argStart:argEnd]), nil
} else if argNum == 1 {
return string(asRunes[argStart:]), nil
} else {
return string(asRunes[:]), nil
}
}
// Split slices an input string into all substrings separated by delimiter.
func (ns *Namespace) Split(a any, delimiter string) ([]string, error) {
aStr, err := cast.ToStringE(a)
if err != nil {View on GitHub (pinned to 52c9bd7908)