gohugoio/hugo · critical

no site

Error message

no site

What it means

Panic in initCommonProviders: for a regular page (IsPage()), the pageState's site reference ps.s must be non-nil because next/prev positioners and providers are wired against the site. A nil site means the page was constructed without being attached to a Site, breaking the build's provider setup.

Source

Thrown at hugolib/page.go:590

	pages, err := ps.s.pageMap.getOrCreatePagesFromCache(nil, key, func(string) (page.Pages, error) {
		var pas page.Pages
		for _, pp := range ps.AllTranslations() {
			if !pp.Eq(ps) {
				pas = append(pas, pp)
			}
		}
		return pas, nil
	})
	if err != nil {
		panic(err)
	}
	return pages
}

func (ps *pageState) initCommonProviders(pp pagePaths) error {
	if ps.IsPage() {
		if ps.s == nil {
			panic("no site")
		}
		ps.posNextPrev = &nextPrev{init: ps.s.init.prevNext}
		ps.posNextPrevSection = &nextPrev{init: ps.s.init.prevNextInSection}
		ps.InSectionPositioner = newPagePositionInSection(ps.posNextPrevSection)
		ps.Positioner = newPagePosition(ps.posNextPrev)
	}

	ps.OutputFormatsProvider = pp
	ps.targetPathDescriptor = pp.targetPathDescriptor
	ps.RefProvider = newPageRef(ps)
	ps.SitesProvider = ps.s
	ps.SiteProvider = ps

	return nil
}

// Exported so it can be used in integration tests.
func (po *pageOutput) GetInternalTemplateBasePathAndDescriptor() (string, tplimpl.TemplateDescriptor) {

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Construct pages through the standard page-map/collector APIs which always bind a Site.
  2. In tests, use hugolib integration-test builders that create a proper Site.
  3. If forking, ensure every pageState gets s set at creation time.
  4. Report a Hugo issue with a reproducer if hit on an unmodified build.

Example fix

// before (fork): page created without site
ps := &pageState{Kind: kinds.KindPage}
ps.initCommonProviders(pp) // panic: no site

// after
ps := &pageState{s: site, Kind: kinds.KindPage}
ps.initCommonProviders(pp)
Defensive patterns

Strategy: validation

Validate before calling

// Internal invariant — ensure pages are created via the page map / collector so the Site is bound.
// In a fork, assert before initCommonProviders:
//   if ps.IsPage() && ps.s == nil { return fmt.Errorf("page %q has no site", ps.Path()) }

Prevention

When it happens

Trigger: A pageState created without an owning Site (ps.s nil) then passed through initCommonProviders. Manual page construction in a fork or test that omits site assignment. A page-decoding path that failed to bind the site.

Common situations: Forking Hugo and constructing pageState directly. Test helpers that build pages without a site. A bug in page collection that drops the site reference (often after a refactor of the page map).

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/4378d48092b3b026. Report an issue: GitHub.