gohugoio/hugo · error
invalid Page received in Ref
Error message
invalid Page received in Ref
What it means
The `ref` template function requires its first argument to implement Hugo's RefLinker interface (a Page). If the value passed as the page context isn't a Page — e.g. a string, dict, or nil — this error is returned before any ref resolution happens.
Source
Thrown at tpl/urls/urls.go:96
}
return ns.deps.PathSpec.URLize(ss), nil
}
// Anchorize creates sanitized anchor name version of the string s that is compatible
// with how your configured markdown renderer does it.
func (ns *Namespace) Anchorize(s any) (string, error) {
ss, err := cast.ToStringE(s)
if err != nil {
return "", err
}
return ns.deps.ContentSpec.SanitizeAnchorName(ss), nil
}
// Ref returns the absolute URL path to a given content item from Page p.
func (ns *Namespace) Ref(p any, args any) (string, error) {
pp, ok := p.(urls.RefLinker)
if !ok {
return "", errors.New("invalid Page received in Ref")
}
argsm, err := ns.refArgsToMap(args)
if err != nil {
return "", err
}
s, err := pp.Ref(argsm)
return s, err
}
// RelRef returns the relative URL path to a given content item from Page p.
func (ns *Namespace) RelRef(p any, args any) (string, error) {
pp, ok := p.(urls.RefLinker)
if !ok {
return "", errors.New("invalid Page received in RelRef")
}
argsm, err := ns.refArgsToMap(args)
if err != nil {
return "", errView on GitHub ↗ (pinned to 8a468df065)
Solutions
- Pass a real Page as the first argument: `{{ ref page "about.md" }}` (Hugo's global `page`) or `{{ ref .Page "about.md" }}` in shortcodes.
- In partials receiving a dict context, include the page: `{{ partial "x" (dict "page" .) }}` then `{{ ref .page "target" }}`.
- Check argument order — the Page comes first, then the ref target.
Example fix
{{/* before, in a shortcode */}}
{{ ref . "about.md" }}
{{/* after */}}
{{ ref .Page "about.md" }} Defensive patterns
Strategy: type-guard
Validate before calling
{{/* ref must be called with a Page as context */}}
{{ with .Page }}{{ ref . "/blog/post" }}{{ end }} Type guard
{{/* narrow to a real Page before calling ref */}}
{{ if reflect.IsMap . | not }}{{ with .Page }}{{ $url := ref . "/docs/intro" }}{{ end }}{{ end }} Try / catch
{{ with try (ref $page "/docs/intro") }}
{{ with .Err }}{{ warnf "ref failed: %s" . }}{{ end }}
{{ end }} Prevention
- Pass the current Page (usually . or $.Page) as ref's first argument — inside range loops or partials the dot is often not a Page
- In shortcodes use {{ ref .Page "target" }}, and in partials pass the page explicitly via the partial's context
- Prefer the relref/ref shortcodes in content, which wire the Page automatically
When it happens
Trigger: `{{ ref "page" "about.md" }}` where the first arg is a string instead of a Page, `{{ ref $someDict "x" }}`, or calling `ref .` inside a shortcode/partial where `.` is the shortcode/partial context rather than a Page.
Common situations: Inside partials where the passed context is a dict (use the `page` global or pass the Page explicitly); inside shortcodes forgetting `.Page` (`{{ ref .Page "x" }}` not `{{ ref . "x" }}`); argument order confusion putting the target path first.
Related errors
- invalid Page received in RelRef
- invalid number of arguments to ref
- invalid arguments to Ref: %w
- error building site: %w
- failed to detect format from content
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/7ca3394c86cb2fbc.json.
Report an issue: GitHub ↗.