{"id":"6e5432998c86de19","repo":"gohugoio/hugo","slug":"failed-to-download-module-s-s-s-s","errorCode":null,"errorMessage":"failed to download module %s@%s: %s: %s","messagePattern":"failed to download module (.+?)@(.+?): (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/client.go","lineNumber":464,"sourceCode":"\tif b, _ := c.ccfg.ModuleQueriesCache.GetBytes(cacheKey); len(b) > 0 {\n\t\tvar cm goModule\n\t\tif err := json.Unmarshal(b, &cm); err == nil && cm.Dir != \"\" {\n\t\t\tif c.isDirNonEmpty(cm.Dir) {\n\t\t\t\treturn &cm, nil\n\t\t\t}\n\t\t}\n\t}\n\n\t// No valid cache, need to query.\n\targs := []string{\"mod\", \"download\", \"-json\", fmt.Sprintf(\"%s@%s\", path, version)}\n\n\tb := &bytes.Buffer{}\n\terr := c.runGo(context.Background(), b, args...)\n\tif err != nil {\n\t\t// The -json flag makes Go output error details as JSON to stdout\n\t\t// even on failure. Try to extract the error message from the JSON output.\n\t\tif jsonErr := extractGoModDownloadError(b.Bytes()); jsonErr != \"\" {\n\t\t\treturn nil, fmt.Errorf(\"failed to download module %s@%s: %s: %s\", path, version, err, jsonErr)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"failed to download module %s@%s: %w\", path, version, err)\n\t}\n\n\tjsonResult := b.Bytes()\n\n\tm := &goModule{}\n\tif err := json.NewDecoder(bytes.NewReader(jsonResult)).Decode(m); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode module download result: %w\", err)\n\t}\n\n\tif m.Error != nil {\n\t\treturn nil, errors.New(m.Error.Err)\n\t}\n\n\t// Cache the successful result if it has a Dir field.\n\tif m.Dir != \"\" {\n\t\t_ = c.ccfg.ModuleQueriesCache.SetBytes(cacheKey, jsonResult)","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/modules/client.go#L446-L482","documentation":"Returned by downloadModuleVersion when `go mod download -json path@version` fails and Go emitted a JSON error payload on stdout. Hugo extracts the detailed message from that JSON and appends it to the process error so the user sees the real cause (e.g. unknown revision) rather than just an exit status.","triggerScenarios":"Downloading a specific module version (e.g. resolving a theme import or version query) where `go mod download -json` exits non-zero but writes a JSON object with an Error field: unknown revision/tag, module path not found, or checksum database rejection.","commonSituations":"Theme config in hugo.toml pinning a version/tag that was deleted or never existed, module repo renamed or made private, GONOSUMDB/GONOSUMCHECK issues with the sum database.","solutions":["Read the appended Go error message — fix the version or tag named in your module import config.","Check available versions with `go list -m -versions <path>`.","For private modules set GOPRIVATE and GONOSUMDB appropriately.","Run `hugo mod clean` and retry to rule out a corrupt cache."],"exampleFix":"# hugo.toml before\n[[module.imports]]\npath = \"github.com/user/theme\"\nversion = \"v9.9.9\"\n# after\nversion = \"v1.4.2\"","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"var lastErr error\nfor attempt := 0; attempt < 3; attempt++ {\n    if err := client.Download(mod); err != nil {\n        lastErr = err\n        if isNetworkErr(err) { time.Sleep(backoff(attempt)); continue }\n        return err // non-transient: bad version, checksum, etc.\n    }\n    return nil\n}\nreturn lastErr","preventionTips":["Retry only transient network/proxy failures with exponential backoff; fail fast on version-not-found","Configure GOPROXY with a fallback (e.g. 'https://proxy.golang.org,direct')","Warm the module cache in CI (cache $GOMODCACHE) so downloads rarely hit the network","Inspect the embedded stderr text to distinguish auth failures (private repos need GOPRIVATE/credentials) from flaky network"],"tags":["go-modules","hugo-mod","download","versioning"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}