gohugoio/hugo · critical

h.ResourceSpec is nil

Error message

h.ResourceSpec is nil

What it means

Panic in writeBuildStats when h.ResourceSpec is nil. writeBuildStats emits the html elements / hash stats used for fingerprinting build output, and it requires the resource spec (configured when Hugo loads resources config). Reaching here with a nil ResourceSpec means the sites object was not fully initialized before stats writing was invoked.

Source

Thrown at hugolib/hugo_sites_build.go:770

	filenames := h.Deps.BuildState.GetFilenamesWithPostPrefix()
	for _, filename := range filenames {
		g.Run(func() error {
			return handleFile(filename)
		})
	}

	// Prepare for a new build.
	for _, s := range h.Sites {
		s.ResourceSpec.PostProcessResources = maphelpers.NewConcurrentMap[string, postpub.PostPublishedResource]()
	}

	return g.Wait()
}

func (h *HugoSites) writeBuildStats() error {
	if h.ResourceSpec == nil {
		panic("h.ResourceSpec is nil")
	}
	if !h.ResourceSpec.BuildConfig().BuildStats.Enabled() {
		return nil
	}

	htmlElements := &publisher.HTMLElements{}
	for _, s := range h.Sites {
		stats := s.publisher.PublishStats()
		htmlElements.Merge(stats.HTMLElements)
	}

	filename := filepath.Join(h.Configs.LoadingInfo.BaseConfig.WorkingDir, files.FilenameHugoStatsJSON)

	existingContent, _ := afero.ReadFile(hugofs.Os, filename)

	// When rendering only a subset of the site, merge with any existing
	// hugo_stats.json so that elements from pages not rendered in this build
	// are preserved (e.g. so Tailwind doesn't strip their classes).

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Initialize HugoSites through the standard LoadConfig/NewHugoSites path so ResourceSpec is set.
  2. If you do not need build stats, disable the feature (build.stats.writeStats = false) to avoid the code path.
  3. Do not nil or reset h.ResourceSpec between builds.
  4. Add your own precondition check before triggering a build that may call writeBuildStats.

Example fix

# hugo.toml
# before (triggers path with a half-initialized sites object)
[build]
writeStats = true

# Ensure HugoSites is built via LoadConfig; if stats unneeded:
# after
[build]
writeStats = false
Defensive patterns

Strategy: validation

Validate before calling

// Ensure ResourceSpec is set (standard init) OR disable build stats:
// hugo.toml:
//   [build]
//   writeStats = false
// If embedding, confirm hugolib.NewHugoSitesFromConfig was used.

Prevention

When it happens

Trigger: Build stats enabled (build.stats in config) but the ResourceSpec was never initialized because the normal HugoSites construction path was bypassed, or it was niled between builds. Calling writeBuildStats directly outside the standard build flow.

Common situations: Embedding Hugo as a library and skipping resource-spec setup. A custom build orchestrator that invokes parts of the pipeline directly. A misconfigured config that enables build stats under an unusual setup.

Related errors


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