{"record":{"id":"3186a56ce5ddf139","repo":"gohugoio/hugo","slug":"must-have-deps","errorCode":null,"errorMessage":"must have deps","messagePattern":"must have deps","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"hugolib/hugo_sites_build.go","lineNumber":91,"sourceCode":"\t\t\th.reportProgress(func() (state terminal.ProgressState, progress float64) {\n\t\t\t\t// We don't know how many files to process below, so use the intermediate state as the first progress.\n\t\t\t\treturn terminal.ProgressIntermediate, 1.0\n\t\t\t})\n\t\t})\n\t\tdefer d(func() {})\n\t}\n\n\tinfol := h.Log.InfoCommand(\"build\")\n\tdefer loggers.TimeTrackf(infol, time.Now(), nil, \"\")\n\tdefer func() {\n\t\th.reportProgress(func() (state terminal.ProgressState, progress float64) {\n\t\t\treturn terminal.ProgressHidden, 1.0\n\t\t})\n\t\th.BuildState.BuildCounter.Add(1)\n\t}()\n\n\tif h.Deps == nil {\n\t\tpanic(\"must have deps\")\n\t}\n\n\tif !config.NoBuildLock {\n\t\tunlock, err := h.BaseFs.LockBuild()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to acquire a build lock: %w\", err)\n\t\t}\n\t\tdefer unlock()\n\t}\n\n\tdefer func() {\n\t\tfor _, s := range h.Sites {\n\t\t\ts.Deps.BuildEndListeners.Notify()\n\t\t}\n\t}()\n\n\terrCollector := h.StartErrorCollector()\n\terrs := make(chan error)","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/hugolib/hugo_sites_build.go#L73-L109","documentation":"Panic raised at the top of HugoSites.Build() when h.Deps is nil. The build pipeline needs the fully-initialized dependency container (filesystems, templates, configs, loggers) before it can render anything. Calling Build() on a HugoSites that was not constructed via the normal config-load path leaves Deps nil, violating a hard precondition. This is an internal invariant guard, not a recoverable runtime condition.","triggerScenarios":"Calling (*HugoSites).Build(cfg) on a zero-value or manually-constructed HugoSites struct without going through hugolib.NewHugoSites / hugolib.LoadHugoConfig / hugolib.NewHugoSitesFromConfig. Also reachable if Depps is explicitly cleared/niled between builds or if a test instantiates HugoSites{} directly.","commonSituations":"Embedding Hugo as a library and skipping the initialization sequence. Test code that hand-builds a HugoSites instead of using the test helpers. A refactor that resets Deps for a rebuild without re-running LoadConfig. Memory/state corruption in long-running processes that reuse the HugoSites object across many builds.","solutions":["Construct HugoSites through hugolib.LoadHugoConfig (or NewHugoSitesFromConfig) which wires up Deps; never call Build() on a bare struct.","If you reuse the object across builds, do not nil out h.Deps between builds; reuse the same dependency container or recreate the whole HugoSites.","In tests, use the hugolib test helpers (e.g. hugolib.NewHugoSitesIntegrationTestBuilder or hugolib.Test) which set up Deps correctly.","Add a nil-check / precondition assertion in your own wrapper before invoking Build so the failure surfaces with your own context."],"exampleFix":"// before\nh := &hugolib.HugoSites{}\nh.Build(config.BuildCfg{}) // panic: must have deps\n\n// after\nh, err := hugolib.NewHugoSitesFromConfig(d, cfg)\nif err != nil { return err }\nh.Build(config.BuildCfg{})","handlingStrategy":"validation","validationCode":"// Before building, ensure HugoSites was created via the standard path.\n// If you hold an *hugolib.HugoSites h:\nfunc isBuildable(h *hugolib.HugoSites) error {\n    // Deps is exported on HugoSites; guard before Build.\n    // (Use reflection or expose a helper if Deps is not directly comparable.)\n    return nil\n}\n// Simplest: only ever obtain h via LoadConfig; treat any nil-Deps object as a bug.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always construct HugoSites through hugolib.LoadHugoConfig / NewHugoSitesFromConfig.","Never reuse a HugoSites after niling its Deps; create a new one.","In tests, use the hugolib integration-test builders.","Treat a nil-Deps HugoSites as a programming bug, not a runtime condition."],"tags":["initialization","deps","build","panic","internal-invariant"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}