{"id":"73f6c49a54951c4c","repo":"gohugoio/hugo","slug":"failed-to-download-module-s-s-w","errorCode":null,"errorMessage":"failed to download module %s@%s: %w","messagePattern":"failed to download module (.+?)@(.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/client.go","lineNumber":466,"sourceCode":"\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)\n\t}\n","sourceCodeStart":448,"sourceCodeEnd":484,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/modules/client.go#L448-L484","documentation":"Same call site as error 102, but the fallback path: `go mod download -json` failed and no JSON error detail could be extracted from stdout, so Hugo wraps only the process error. Usually indicates the go command failed before producing module-level output (environment or network level failure).","triggerScenarios":"`go mod download -json path@version` exiting non-zero with empty or non-JSON stdout: go binary crash, GOPROXY unreachable, DNS failure, disk full in the module cache, or invalid GOFLAGS.","commonSituations":"Offline builds/CI without vendoring, misconfigured GOPROXY/GONOSUMDB env vars in CI, module cache permission problems (cache created by a different user, e.g. root in Docker).","solutions":["Check network access to the module proxy or set GOPROXY=direct.","Inspect stderr from Hugo's output for the underlying go error.","Fix GOMODCACHE permissions or clear it (`go clean -modcache`).","Vendor modules (`hugo mod vendor`) for offline/CI builds."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := client.Download(mod); err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) && netErr.Timeout() {\n        // transient — retry with backoff\n    } else {\n        return err\n    }\n}","preventionTips":["Use errors.As/errors.Is on the wrapped cause to classify before retrying","Set GOFLAGS=-mod=mod only when mutation is intended; use vendoring in air-gapped builds so download is never needed","Pre-verify the version exists via 'go list -m -versions <path>' in diagnostics tooling"],"tags":["go-modules","hugo-mod","download","network","environment"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}