{"record":{"id":"335fa6018269f1b8","repo":"gohugoio/hugo","slug":"h-resourcespec-is-nil","errorCode":null,"errorMessage":"h.ResourceSpec is nil","messagePattern":"h\\.ResourceSpec is nil","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"hugolib/hugo_sites_build.go","lineNumber":770,"sourceCode":"\n\tfilenames := h.Deps.BuildState.GetFilenamesWithPostPrefix()\n\tfor _, filename := range filenames {\n\t\tg.Run(func() error {\n\t\t\treturn handleFile(filename)\n\t\t})\n\t}\n\n\t// Prepare for a new build.\n\tfor _, s := range h.Sites {\n\t\ts.ResourceSpec.PostProcessResources = maphelpers.NewConcurrentMap[string, postpub.PostPublishedResource]()\n\t}\n\n\treturn g.Wait()\n}\n\nfunc (h *HugoSites) writeBuildStats() error {\n\tif h.ResourceSpec == nil {\n\t\tpanic(\"h.ResourceSpec is nil\")\n\t}\n\tif !h.ResourceSpec.BuildConfig().BuildStats.Enabled() {\n\t\treturn nil\n\t}\n\n\thtmlElements := &publisher.HTMLElements{}\n\tfor _, s := range h.Sites {\n\t\tstats := s.publisher.PublishStats()\n\t\thtmlElements.Merge(stats.HTMLElements)\n\t}\n\n\tfilename := filepath.Join(h.Configs.LoadingInfo.BaseConfig.WorkingDir, files.FilenameHugoStatsJSON)\n\n\texistingContent, _ := afero.ReadFile(hugofs.Os, filename)\n\n\t// When rendering only a subset of the site, merge with any existing\n\t// hugo_stats.json so that elements from pages not rendered in this build\n\t// are preserved (e.g. so Tailwind doesn't strip their classes).","sourceCodeStart":752,"sourceCodeEnd":788,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/hugolib/hugo_sites_build.go#L752-L788","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# hugo.toml\n# before (triggers path with a half-initialized sites object)\n[build]\nwriteStats = true\n\n# Ensure HugoSites is built via LoadConfig; if stats unneeded:\n# after\n[build]\nwriteStats = false","handlingStrategy":"validation","validationCode":"// Ensure ResourceSpec is set (standard init) OR disable build stats:\n// hugo.toml:\n//   [build]\n//   writeStats = false\n// If embedding, confirm hugolib.NewHugoSitesFromConfig was used.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["resources","build-stats","initialization","panic","internal-invariant"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}