gohugoio/hugo · error

wrong number of args for default: want 2 got

Error message

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

What it means

`compare.Default` (compare.go:48-58) is variadic: `Default(defaultv any, givenv ...any)`. It accepts zero or one given value (zero is the piped-missing case at line 53). If `len(givenv)` is greater than 1, it returns this error reporting the total count (`len(givenv)+1`). Hugo only supports one value to test against the default.

Solutions

  1. Pass exactly one given value: `{{ default "a" "b" }}`.
  2. For a multi-value fallback chain, nest `default` calls or use `or`: `{{ or $a $b $c $fallback }}`.
  3. Remove stray piped + positional argument combinations.

Example fix

// before
{{ default "a" "b" "c" }}
// after
{{ default "a" "b" }}
{{/* or for chaining */}}
{{ or $b $c "a" }}
Defensive patterns

Strategy: validation

Validate before calling

{{/* default takes exactly one optional given value; chain with or for more */}}
{{ default "a" $maybe }}
{{ or $a $b $c "fallback" }}

Prevention

When it happens

Trigger: `{{ default "a" "b" "c" }}` passing two given values; `{{ "x" | default "a" "b" }}` combining a pipe with extra positional args.

Common situations: Author treats `default` as a multi-arg coalesce/first-non-empty; leftover args from refactoring; confusing `default` with `cond`/`or`.

Related errors


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

Appendix: 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 52c9bd7908)