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() != 0View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Use exactly two values: `{{ default "fallback" .Value }}` or `{{ .Value | default "fallback" }}`.
- For multiple fallbacks, chain: `{{ .A | default .B | default "x" }}`.
- 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
- Always call default with exactly two arguments: the default value first, then the input
- In pipelines, remember the piped value becomes the last argument: {{ .Params.x | default "y" }} is already two args — don't add another
- Parenthesize nested calls so argument grouping is explicit: default "x" (index .Params "key")
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
- need at least 2 arguments to append
- must provide a Resource and optionally an options map
- operator argument must be string type
- can't evaluate the array by no match argument or more than o
- invalid arguments supplied to `time`
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/fb8d7bda69229d3f.json.
Report an issue: GitHub ↗.