gohugoio/hugo · error

wrong number of args for default: want 2 got %d

Error message

wrong number of args for default: want 2 got %d

What it means

The `default` template function takes exactly one default value and one given value. Its second parameter is variadic only to tolerate the piped-with-missing-key case; if more than one 'given' value arrives, Hugo reports the total argument count (len+1) with this error.

Source

Thrown at tpl/compare/compare.go:57

	loc *time.Location
	// Enable to do case insensitive string compares.
	caseInsensitive bool
}

// Default checks whether a givenv is set and returns the default value defaultv if it
// is not.  "Set" in this context means non-zero for numeric types and times;
// non-zero length for strings, arrays, slices, and maps;
// any boolean or struct value; or non-nil for any other types.
func (*Namespace) Default(defaultv any, givenv ...any) (any, error) {
	// given is variadic because the following construct will not pass a piped
	// argument when the key is missing:  {{ index . "key" | default "foo" }}
	// The Go template will complain that we got 1 argument when we expected 2.

	if len(givenv) == 0 {
		return defaultv, nil
	}
	if len(givenv) != 1 {
		return nil, fmt.Errorf("wrong number of args for default: want 2 got %d", len(givenv)+1)
	}

	g := reflect.ValueOf(givenv[0])
	if !g.IsValid() {
		return defaultv, nil
	}

	set := false

	switch g.Kind() {
	case reflect.Bool:
		set = true
	case reflect.String, reflect.Array, reflect.Slice, reflect.Map:
		set = g.Len() != 0
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		set = g.Int() != 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		set = g.Uint() != 0

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Use exactly two values: `{{ default "fallback" .Value }}` or `{{ .Value | default "fallback" }}`.
  2. For multiple fallbacks, chain: `{{ .A | default .B | default "x" }}`.
  3. When piping, remove the explicit second argument — the piped value fills it.

Example fix

{{/* before */}}
{{ .Params.title | default .Site.Title "Untitled" }}
{{/* after */}}
{{ .Params.title | default .Site.Title | default "Untitled" }}
Defensive patterns

Strategy: validation

Validate before calling

{{/* default takes exactly two args: default DEFAULT INPUT */}}
{{ $v := default "fallback" .Params.subtitle }}

Prevention

When it happens

Trigger: `{{ default "x" .A .B }}` — calling default with three or more arguments, or piping into a default that already has two explicit arguments (`{{ .A | default "x" .B }}`).

Common situations: Misunderstanding argument order and adding extras, confusing `default` with a coalesce-style function that scans multiple candidates, or a pipe silently appending the piped value as an extra argument after two explicit ones.

Related errors


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