{"id":"0552f1e258e09cce","repo":"gohugoio/hugo","slug":"page-reference-q-is-ambiguous","errorCode":null,"errorMessage":"page reference %q is ambiguous","messagePattern":"page reference %q is ambiguous","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hugolib/pagecollections.go","lineNumber":218,"sourceCode":"\tif hadExtension && s.home != nil && s.home.File() != nil {\n\t\tif n, err := c.getContentNodeFromRefReverseLookup(inRef, s.home.File().FileInfo()); n != nil || err != nil {\n\t\t\treturn n, err\n\t\t}\n\t}\n\n\tvar doSimpleLookup bool\n\tif isReflink || context == nil {\n\t\tslashCount := strings.Count(inRef, \"/\")\n\t\tdoSimpleLookup = slashCount == 0\n\t}\n\n\tif !doSimpleLookup {\n\t\treturn nil, nil\n\t}\n\n\tn = c.pm.pageReverseIndex.Get(nameNoIdentifier)\n\tif n == ambiguousContentNode {\n\t\treturn nil, fmt.Errorf(\"page reference %q is ambiguous\", inRef)\n\t}\n\n\treturn n, nil\n}\n\nfunc (c *pageFinder) getContentNodeFromRefReverseLookup(ref string, fi hugofs.FileMetaInfo) (contentNode, error) {\n\ts := c.pm.s\n\tmeta := fi.Meta()\n\tdir := meta.Filename\n\tif !fi.IsDir() {\n\t\tdir = filepath.Dir(meta.Filename)\n\t}\n\n\trealFilename := filepath.Join(dir, ref)\n\n\tpcs, err := s.BaseFs.Content.ReverseLookup(realFilename, true)\n\tif err != nil {\n\t\treturn nil, err","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/hugolib/pagecollections.go#L200-L236","documentation":"Hugo's pageFinder resolves a page reference (from ref/relref shortcodes, .GetPage, or link render hooks) via a reverse index keyed by the base filename without identifiers. When the same base name (e.g. `about.md`) exists in multiple sections, the index stores an `ambiguousContentNode` sentinel, and any simple (no-slash) lookup of that name fails with this error because Hugo cannot know which page you meant.","triggerScenarios":"Calling `.GetPage \"about\"`, `{{< ref \"about\" >}}`, or `{{< relref \"mypage.md\" >}}` with a bare filename (no path separators) when two or more content files share that base name in different directories, e.g. `content/blog/about.md` and `content/company/about.md`. Only the simple-lookup path at pagecollections.go:216 hits this; path-qualified refs bypass it.","commonSituations":"Large multilingual or multi-section sites with recurring filenames like `index.md`, `overview.md`, or `faq.md`; content migrated from other SSGs where duplicate slugs were fine; shortcodes copied from docs that use bare filenames; sites that grew a second section containing a filename that used to be unique.","solutions":["Qualify the reference with its section path: `{{< ref \"/company/about\" >}}` or `.GetPage \"/company/about.md\"` instead of the bare name.","Search the content tree for duplicates (`find content -name 'about*'`) and rename one file if the duplication is accidental.","For links relative to the current page, use a leading `./` or the page's full path so the reverse-index simple lookup is never used."],"exampleFix":"<!-- before -->\n{{< ref \"about\" >}}\n<!-- after -->\n{{< ref \"/company/about\" >}}","handlingStrategy":"validation","validationCode":"// Use unambiguous page refs in templates/content:\n// {{ .Site.GetPage \"/posts/my-post\" }} — full path from content root\n// instead of a bare filename like {{ .Site.GetPage \"my-post\" }}\n// Audit for bare refs:\n// grep -rn 'GetPage \"' layouts/ content/ | grep -v 'GetPage \"/'","typeGuard":null,"tryCatchPattern":"p, err := s.GetPage(ref)\nif err != nil {\n    return fmt.Errorf(\"resolve %q: use a full path from the content root to disambiguate: %w\", ref, err)\n}","preventionTips":["Always reference pages by full content-root-relative path (\"/posts/foo\") rather than bare filenames","Avoid duplicate page filenames across sections when you rely on short refs","When using relref/ref shortcodes, pass the section-qualified path","Add a CI build (hugo --panicOnWarning) so ambiguous refs fail fast"],"tags":["hugo","content","ref-resolution","ambiguity"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}