gohugoio/hugo · error
failed to decode module download result: %w
Error message
failed to decode module download result: %w
What it means
Returned when `go mod download -json` succeeded (exit 0) but the JSON it wrote to stdout could not be decoded into Hugo's goModule struct. It signals corrupted or unexpected output from the Go toolchain rather than a download failure per se.
Source
Thrown at modules/client.go:473
// No valid cache, need to query.
args := []string{"mod", "download", "-json", fmt.Sprintf("%s@%s", path, version)}
b := &bytes.Buffer{}
err := c.runGo(context.Background(), b, args...)
if err != nil {
// The -json flag makes Go output error details as JSON to stdout
// even on failure. Try to extract the error message from the JSON output.
if jsonErr := extractGoModDownloadError(b.Bytes()); jsonErr != "" {
return nil, fmt.Errorf("failed to download module %s@%s: %s: %s", path, version, err, jsonErr)
}
return nil, fmt.Errorf("failed to download module %s@%s: %w", path, version, err)
}
jsonResult := b.Bytes()
m := &goModule{}
if err := json.NewDecoder(bytes.NewReader(jsonResult)).Decode(m); err != nil {
return nil, fmt.Errorf("failed to decode module download result: %w", err)
}
if m.Error != nil {
return nil, errors.New(m.Error.Err)
}
// Cache the successful result if it has a Dir field.
if m.Dir != "" {
_ = c.ccfg.ModuleQueriesCache.SetBytes(cacheKey, jsonResult)
}
return m, nil
}
// isDirNonEmpty returns true if dir exists and contains at least one file or subdirectory.
func (c *Client) isDirNonEmpty(dir string) bool {
f, err := c.fs.Open(dir)
if err != nil {View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Run `go mod download -json <path>@<version>` manually and inspect the raw output.
- Remove wrappers/aliases around the go binary that print extra output.
- Unset GOFLAGS/GODEBUG values that alter go command output.
- Upgrade Hugo and Go to compatible recent versions.
Defensive patterns
Strategy: try-catch
Type guard
func isDecodeErr(err error) bool {
var syntaxErr *json.SyntaxError
var typeErr *json.UnmarshalTypeError
return errors.As(err, &syntaxErr) || errors.As(err, &typeErr)
} Try / catch
if err := client.Download(mods); err != nil {
if isDecodeErr(err) {
// go tool output was malformed — likely go version mismatch or GOFLAGS polluting stdout
return fmt.Errorf("unexpected 'go mod download -json' output; check Go version compatibility: %w", err)
}
return err
} Prevention
- Keep the Go toolchain within the version range Hugo supports — decode failures usually mean the -json output shape changed
- Ensure GOFLAGS/GODEBUG don't inject non-JSON text into the go command's stdout
- Report the raw output alongside the error when filing issues instead of retrying
When it happens
Trigger: json.Decoder failing on `go mod download -json` output: non-JSON noise interleaved on stdout (wrappers, GODEBUG output), a truncated buffer, or a Go version emitting an incompatible format.
Common situations: Shell wrappers or scripts around the `go` binary that print to stdout, GOFLAGS injecting flags that change output, or very new/old Go releases changing the -json schema.
Related errors
- failed to decode modules list: %w
- failed to get %q: %w
- failed to init modules: %w
- failed to download module %s@%s: %s: %s
- failed to download module %s@%s: %w
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/eaa85c9ef575f6df.json.
Report an issue: GitHub ↗.