gohugoio/hugo · error

end argument must be integer

Error message

end argument must be integer

What it means

In `strings.SliceString`, the optional second index (end) is cast with `cast.ToIntE`. A value that can't be converted to an int aborts template execution with this error, keeping the half-open range semantics strict rather than silently defaulting.

Source

Thrown at tpl/strings/strings.go:335

// The end index can be omitted, it defaults to the string's length.
func (ns *Namespace) SliceString(a any, startEnd ...any) (string, error) {
	aStr, err := cast.ToStringE(a)
	if err != nil {
		return "", err
	}

	var argStart, argEnd int

	argNum := len(startEnd)

	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

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Pass an integer end index: `{{ slicestr $s 0 3 }}`
  2. Coerce dynamic values with `int`: `{{ slicestr $s 0 (int .Params.end) }}`
  3. Omit the end argument entirely if you want to slice to the end of the string

Example fix

// before
{{ slicestr "BatMan" 0 "3" x }}
// after
{{ slicestr "BatMan" 0 3 }}
Defensive patterns

Strategy: type-guard

Validate before calling

{{ $end := int (default (len .s) .end) }}
{{ substr .s 0 $end }}

Type guard

{{ $end := .end }}{{ if $end }}{{ $end = int $end }}{{ end }}

Try / catch

{{ with try (substr .s 0 .end) }}{{ if .Err }}{{ warnf "%s" .Err }}{{ else }}{{ .Value }}{{ end }}{{ end }}

Prevention

When it happens

Trigger: Calling `slicestr` with three arguments where the third (end index) is non-numeric: `{{ slicestr "BatMan" 0 "end" }}`, or an end index sourced from a param/variable holding a non-numeric value or nil.

Common situations: End index read from front matter as a string; passing `len $s` results wrapped in unexpected types; copy-pasted examples where the end argument is a word; nil params on pages missing the field.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/7335e6b7c7215494.json. Report an issue: GitHub ↗.