{"record":{"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/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/hugolib/pagecollections.go#L200-L236","documentation":"Raised by getContentNodeForRef (pagecollections.go:218) during a simple (no-slash) ref lookup when the pageReverseIndex returns the ambiguousContentNode sentinel. That sentinel is set when two or more distinct content nodes share the same base-name-without-identifier, so a bare name like {{< ref \"about\" >}} cannot be resolved to a single page.","triggerScenarios":"Two files named about.md in different sections; a content file and a branch bundle sharing a base name; using a bare filename ref (no path) where multiple pages collide on that name. Only triggers for refs with zero slashes (doSimpleLookup at line 209).","commonSituations":"Multilingual content where the same slug exists per language but lookup crosses languages; an about.md at content root and another in a section; renaming files such that base names now clash.","solutions":["Use a more specific path in the ref: `{{< ref \"/company/about.md\" >}}` instead of `{{< ref \"about\" >}}`.","Rename one of the colliding files so the base name is unique.","If the duplicate is unintentional, delete or move the redundant content file."],"exampleFix":"{{/* before */}}\n{{< ref \"about\" >}}\n\n{{/* after */}}\n{{< ref \"/company/about.md\" >}}","handlingStrategy":"validation","validationCode":"# Detect base-name collisions across content files before building.\nfind content -type f \\( -name '*.md' -o -name '*.adoc' \\) -printf '%f\\n' | sort | uniq -d","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use fully qualified paths in refs ({{< ref \"/section/page.md\" >}}) to avoid ambiguity.","Keep content file base names unique across the project.","Periodically run the collision check above in CI."],"tags":["ref","content","disambiguation"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}