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
- Initialize HugoSites through the standard LoadConfig/NewHugoSites path so ResourceSpec is set.
- If you do not need build stats, disable the feature (build.stats.writeStats = false) to avoid the code path.
- Do not nil or reset h.ResourceSpec between builds.
- 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
- Initialize HugoSites via LoadConfig so ResourceSpec is populated.
- Disable build stats if you do not need them.
- Do not reset ResourceSpec between builds.
- Add a precondition check before invoking stats-emitting code paths.
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
- must have deps
- resource %d to post process is nil
- nil deps on site
- deferred execution with id %q not found
- template %q not found
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/335fa6018269f1b8.
Report an issue: GitHub.