gohugoio/hugo · error

length argument must be an integer

Error message

length argument must be an integer

What it means

When `substr` is called with two extra arguments (start and length), the length is converted with `cast.ToIntE`. A length value that can't be cast to an int — a non-numeric string, map, slice, or nil — produces this error, since Hugo won't guess how many characters you meant.

Source

Thrown at tpl/strings/strings.go:407

	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 {
		start += rlen
	}

	// start was originally negative beyond rlen
	if start < 0 {
		start = 0
	}

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Pass an integer length: `{{ substr $s 0 30 }}`
  2. Coerce config/param values: `{{ substr $s 0 (int site.Params.summaryLength) }}`
  3. Guard optional params with `with`/`default`: `{{ substr $s 0 (default 30 .Params.len) }}`

Example fix

// before
{{ substr .Summary 0 .Params.len }}  <!-- len: "thirty" -->
// after
{{ substr .Summary 0 (int (default 30 .Params.len)) }}
Defensive patterns

Strategy: type-guard

Validate before calling

{{ $n := int (default 70 site.Params.truncateLen) }}
{{ truncate $n .Summary }}

Type guard

{{ $n := .Params.maxLen }}{{ if $n }}{{ $n = int $n }}{{ else }}{{ $n = 70 }}{{ end }}

Try / catch

{{ with try (truncate .n .text) }}{{ if .Err }}{{ warnf "%s" .Err }}{{ .text }}{{ else }}{{ .Value }}{{ end }}{{ end }}

Prevention

When it happens

Trigger: `{{ substr "hello" 0 "abc" }}`, or a length sourced from `.Params`/`site.Params` that holds a non-numeric string or is unset on some pages.

Common situations: Summary-length settings stored as strings like "30 chars" in config; passing the ellipsis or suffix string in the length position; nil front-matter fields on a subset of pages breaking only those builds.

Related errors


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