gohugoio/hugo · error
wrong number of arguments, expecting at most 2, got %d
Error message
wrong number of arguments, expecting at most 2, got %d
What it means
Hugo's `lang.Translate` (template function `T`/`i18n`) accepts a translation id plus at most one optional template-data argument. This error is returned from `Namespace.Translate` in tpl/lang/lang.go when more than one variadic arg is passed after the id; the reported count is len(args)+1 to include the id itself.
Source
Thrown at tpl/lang/lang.go:51
return &Namespace{
translator: translator,
deps: deps,
}
}
// Namespace provides template functions for the "lang" namespace.
type Namespace struct {
translator golocales.Translator
deps *deps.Deps
}
// Translate returns a translated string for id.
func (ns *Namespace) Translate(ctx context.Context, id any, args ...any) (string, error) {
var templateData any
if len(args) > 0 {
if len(args) > 1 {
return "", fmt.Errorf("wrong number of arguments, expecting at most 2, got %d", len(args)+1)
}
templateData = args[0]
}
sid, err := cast.ToStringE(id)
if err != nil {
return "", err
}
return ns.deps.Translate(ctx, sid, templateData), nil
}
// FormatNumber formats number with the given precision for the current language.
func (ns *Namespace) FormatNumber(precision, number any) (string, error) {
p, n, err := ns.castPrecisionNumber(precision, number)
if err != nil {
return "", err
}View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Pass at most one data argument: wrap multiple values in a dict, e.g. `{{ i18n "key" (dict "Name" .Name "Count" .Count) }}`.
- In the i18n TOML/YAML file, reference the dict fields via Go template placeholders like `{{ .Name }}`.
- If piping, remember the piped value counts as the last argument — restructure the call so only id + one data value reach T.
Example fix
<!-- before -->
{{ i18n "welcome" .Name .Count }}
<!-- after -->
{{ i18n "welcome" (dict "Name" .Name "Count" .Count) }} Defensive patterns
Strategy: validation
Validate before calling
{{/* lang.FormatNumber takes at most 2 args: precision, number */}}
{{ $args := slice 2 1234.56 }}
{{ if le (len $args) 2 }}{{ lang.FormatNumber 2 1234.56 }}{{ end }} Try / catch
{{ with try (lang.FormatNumber 2 1234.56 3) }}{{ with .Err }}{{ warnf "%s" . }}{{ else }}{{ .Value }}{{ end }}{{ end }} Prevention
- Call lang.* format functions with exactly (precision, number) or just (number) — never pass extra positional args
- Check the Hugo docs signature before piping values, since piping adds the final argument implicitly
- Avoid spreading user-built slices into function calls; construct the call explicitly
When it happens
Trigger: Calling `{{ T "greeting" .Data extraArg }}` or `{{ i18n "key" arg1 arg2 }}` — any invocation with three or more total arguments to the T/i18n/lang.Translate template function.
Common situations: Developers coming from other i18n systems that take multiple positional placeholders (e.g. printf-style) pass several values instead of one context object; or a pipeline accidentally appends an extra argument (`{{ .Title | i18n "key" .Params }}`).
Related errors
- start argument must be integer
- end argument must be integer
- length argument must be an integer
- language %q not found
- errConfigNotSet
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/d61e974be26a3428.json.
Report an issue: GitHub ↗.