gohugoio/hugo · error

too few arguments

Error message

too few arguments

What it means

Hugo's `strings.Substr` requires at least a start position after the string; with zero variadic arguments there is nothing to extract, so it fails fast with "too few arguments" rather than returning the whole string.

Source

Thrown at tpl/strings/strings.go:396

// To extract characters from the end of the string, use a negative start number.
//
// In addition, borrowing from the extended behavior described at http://php.net/substr,
// 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

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Provide at least a start index: `{{ substr "hello" 1 }}`
  2. Provide start and length for a bounded extract: `{{ substr "hello" 1 3 }}`
  3. If you just wanted the whole string, drop the `substr` call entirely

Example fix

// before
{{ substr .Title }}
// after
{{ substr .Title 0 10 }}
Defensive patterns

Strategy: validation

Validate before calling

{{/* truncate needs at least a length: */}}
{{ if and .len .text }}{{ truncate .len .text }}{{ end }}

Try / catch

{{ with try (truncate .len .text) }}{{ if .Err }}{{ errorf "truncate misuse: %s" .Err }}{{ end }}{{ end }}

Prevention

When it happens

Trigger: Calling `substr` with only the string: `{{ substr "hello" }}`, or a pipeline like `{{ .Title | substr }}` where no start/length arguments are given.

Common situations: Confusing `substr` with functions that have sensible no-arg defaults; refactoring a template and dropping the index arguments; dynamically built calls where a param evaluated to nothing.

Related errors


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