gohugoio/hugo · error

invalid arguments to Ref: %w

Error message

invalid arguments to Ref: %w

What it means

The `ref`/`relref` template functions (and shortcodes) accept either a path string or an options map (path, lang, outputFormat). decodeRefArgs normalizes the input and mapstructure-decodes the map into refArgs; if that argument shape can't be interpreted at all, ref returns this error. Note the mapstructure decode error itself is swallowed at line 52 — this wrapper fires when the surrounding arg normalization fails.

Source

Thrown at hugolib/page__ref.go:79

			if ss.Lang() == ra.Lang {
				found = true
				s = ss
			}
		}

		if !found {
			p.p.s.siteRefLinker.logNotFound(ra.Path, fmt.Sprintf("no site found with lang %q", ra.Lang), nil, text.Position{})
			return ra, nil, nil
		}
	}

	return ra, s, nil
}

func (p pageRef) ref(argsm map[string]any, source any) (string, error) {
	args, s, err := p.decodeRefArgs(argsm)
	if err != nil {
		return "", fmt.Errorf("invalid arguments to Ref: %w", err)
	}

	if s == nil {
		return p.p.s.siteRefLinker.notFoundURL, nil
	}

	if args.Path == "" {
		return "", nil
	}

	return s.siteRefLinker.refLink(args.Path, source, false, args.OutputFormat)
}

func (p pageRef) relRef(argsm map[string]any, source any) (string, error) {
	args, s, err := p.decodeRefArgs(argsm)
	if err != nil {
		return "", fmt.Errorf("invalid arguments to Ref: %w", err)
	}

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Pass either a plain string path (`{{ ref . "about.md" }}`) or a flat dict: `{{ .Ref (dict "path" "/about" "lang" "fr" "outputFormat" "amp") }}`.
  2. Inspect the dynamic values you feed into the args dict — ensure path/lang/outputFormat are strings.
  3. Check the wrapped error message for which field failed to decode and fix its type.

Example fix

{{/* before */}}
{{ .Ref (dict "path" .Page) }}

{{/* after */}}
{{ .Ref (dict "path" .Page.Path) }}
Defensive patterns

Strategy: validation

Validate before calling

{{/* validate args before calling .Ref */}}
{{ $args := dict "path" "/posts/foo" "outputFormat" "html" }}
{{ if not (isset $args "path") }}{{ errorf "Ref requires path" }}{{ end }}

Try / catch

{{ with try (.Ref (dict "path" $p)) }}
  {{ with .Err }}{{ warnf "bad ref %q: %s" $p . }}{{ else }}{{ .Value }}{{ end }}
{{ end }}

Prevention

When it happens

Trigger: Calling `.Ref`/`.RelRef` (or the ref/relref shortcodes) with arguments that aren't a string or a map decodable to {path, lang, outputFormat} — e.g. passing a slice, a page object, or a map with values of wildly wrong types from a template like `{{ .Ref (dict "path" .Pages) }}`.

Common situations: Custom shortcodes or partials that build the ref args dict dynamically and pass a non-string value for path/lang/outputFormat; migrating old templates that passed positional args incorrectly; typos producing nested structures instead of flat maps.

Related errors


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