{"id":"28dbc8aa03484b02","repo":"gohugoio/hugo","slug":"failed-to-load-modules-w","errorCode":null,"errorMessage":"failed to load modules: %w","messagePattern":"failed to load modules: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/allconfig/load.go","lineNumber":78,"sourceCode":"\n\tl := &configLoader{ConfigSourceDescriptor: d, cfg: config.New()}\n\t// Make sure we always do this, even in error situations,\n\t// as we have commands (e.g. \"hugo mod init\") that will\n\t// use a partial configuration to do its job.\n\tdefer l.deleteMergeStrategies()\n\tres, _, err := l.loadConfigMain(d)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to load config: %w\", err)\n\t}\n\n\tconfigs, err = fromLoadConfigResult(d.Fs, d.Logger, res)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create config from result: %w\", err)\n\t}\n\n\tmoduleConfig, modulesClient, err := l.loadModules(configs, d.IgnoreModuleDoesNotExist)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to load modules: %w\", err)\n\t}\n\n\tif len(l.ModulesConfigFiles) > 0 {\n\t\t// Config merged in from modules.\n\t\t// Re-read the config.\n\t\tconfigs, err = fromLoadConfigResult(d.Fs, d.Logger, res)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to create config from modules config: %w\", err)\n\t\t}\n\t\tif err := configs.transientErr(); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to create config from modules config: %w\", err)\n\t\t}\n\t\tconfigs.LoadingInfo.ConfigFiles = append(configs.LoadingInfo.ConfigFiles, l.ModulesConfigFiles...)\n\t} else if err := configs.transientErr(); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create config: %w\", err)\n\t}\n\n\tconfigs.Modules = moduleConfig.AllModules","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/config/allconfig/load.go#L60-L96","documentation":"Returned when l.loadModules fails — the step that resolves the site's module graph (theme(s), Hugo Modules from [module.imports], their transitive imports and mounts) using the modules client. It wraps errors from Go-module resolution, filesystem mounting, or missing themes/modules, unless IgnoreModuleDoesNotExist is set for commands like `hugo mod init`.","triggerScenarios":"theme = 'x' or [[module.imports]] path pointing at a theme/module that doesn't exist in themes/ or can't be fetched; running module-based sites without Go installed or without network access; a corrupt module cache; go.mod/go.sum inconsistencies; invalid [module.mounts] source paths.","commonSituations":"Cloning a site without `git submodule update --init` so themes/<name> is empty; CI without Go installed for a Hugo Modules site; private module repos without credentials (GOPRIVATE/netrc); typo in the theme name; offline builds needing `hugo mod vendor`.","solutions":["If the theme is a git submodule, run `git submodule update --init --recursive` so themes/<name> is populated.","For Hugo Modules, ensure Go is installed and run `hugo mod get` / `hugo mod tidy`; check network and GOPRIVATE for private repos.","Verify the theme/module path in config matches the directory or repo path exactly.","Clear a corrupt cache with `hugo mod clean`, or vendor dependencies with `hugo mod vendor` for hermetic builds."],"exampleFix":"# before (CI)\nhugo --minify   # themes/ananke empty\n# after\ngit submodule update --init --recursive\nhugo --minify","handlingStrategy":"retry","validationCode":"// Verify module prerequisites before loading\nif _, err := exec.LookPath(\"go\"); err != nil {\n    return errors.New(\"hugo modules require the go binary on PATH\")\n}\nif _, err := os.Stat(filepath.Join(workingDir, \"go.mod\")); err != nil {\n    // module config present but no go.mod → run hugo mod init first\n}","typeGuard":null,"tryCatchPattern":"conf, err := allconfig.LoadConfig(opts)\nif err != nil {\n    // module fetches hit the network; retry transient failures a bounded number of times,\n    // but treat resolution errors (bad module path/version) as permanent\n    if isTransientNetErr(err) { /* bounded retry with backoff */ }\n    return err\n}","preventionTips":["Distinguish transient network/proxy failures (retryable, bounded) from bad module paths or versions (fix the config)","Vendor modules (hugo mod vendor) so builds don't depend on network availability","Commit go.mod/go.sum and keep them in sync with the [module] imports","Set HUGO_MODULE_PROXY/GOPROXY explicitly in CI for reproducible fetches"],"tags":["hugo","modules","themes","go-modules"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}