gohugoio/hugo · error

start argument must be an integer

Error message

start argument must be an integer

What it means

Thrown by the strings.Substr template function when called with one variadic argument that cannot be cast to an integer (the start position). Substr's signature is Substr(a any, nums ...any); with exactly one num, that num is treated as the start index and must be a whole number. Hugo surfaces this as a template rendering error with the message 'start argument must be an integer'.

Source

Thrown at tpl/strings/strings.go:399

// if length is given and is negative, then that many characters will be omitted from
// the end of string.
func (ns *Namespace) Substr(a any, nums ...any) (string, error) {
	s, err := cast.ToStringE(a)
	if err != nil {
		return "", err
	}

	asRunes := []rune(s)
	rlen := len(asRunes)

	var start, length int

	switch len(nums) {
	case 0:
		return "", errors.New("too few arguments")
	case 1:
		if start, err = cast.ToIntE(nums[0]); err != nil {
			return "", errors.New("start argument must be an integer")
		}
		length = rlen
	case 2:
		if start, err = cast.ToIntE(nums[0]); err != nil {
			return "", errors.New("start argument must be an integer")
		}
		if length, err = cast.ToIntE(nums[1]); err != nil {
			return "", errors.New("length argument must be an integer")
		}
	default:
		return "", errors.New("too many arguments")
	}

	if rlen == 0 {
		return "", nil
	}

	if start < 0 {

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Coerce the start argument to an integer before calling, e.g. {{ substr .Title (int .StartVar) }}.
  2. Verify the value is numeric: {{ with .StartVar }}{{ if (eq (printf "%T" .) "int") }}...{{ end }}{{ end }}.
  3. Fix the upstream data source so the parameter is stored as a number in front matter.

Example fix

// before
{{ substr .Title .Offset }}
// after
{{ substr .Title (int .Offset) }}
Defensive patterns

Strategy: validation

Validate before calling

{{ $start := int .Offset }}
{{ substr .Title $start }}

Prevention

When it happens

Trigger: Calling {{ substr "hello" "x" }} or {{ "hello" | substr 2.5 }} or {{ substr .Title .SomeStringVar }} where the single num argument is a non-integer string, float, or nil.

Common situations: Passing a front matter value that was parsed as a string (e.g. a page parameter) instead of a number; using a computed value that resolves to a float; copy-pasting a PHP-style substr example with string offsets.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/468114266d112458. Report an issue: GitHub.