gohugoio/hugo · error

failed to decode

Error message

failed to decode %q: %w

What it means

Generic decoder-level error emitted by decodeConfigFromParams. It runs each registered section decoder (an entry in allDecoderSetups: build, languages, markup, mediatypes, outputformats, caches, etc.) in dependency order. When any single decoder returns an error, it is wrapped with that decoder's key so you know which top-level config section failed. This is the common ancestor of the more specific "failed to decode languages config" and "failed to decode related config" errors.

Solutions

  1. The wrapped error and the quoted key identify the failing section. Open that section and validate field types against current Hugo docs.
  2. Run `hugo config` to see how far decoding got before failing.
  3. Comment out the named section; if the build proceeds, the problem is isolated to it.
  4. Compare the section against a freshly generated `hugo new site` default.

Example fix

# before (outputformats missing isPlainText)
[outputFormats.MYFORMAT]
mediaType = "text/html"

# after
[outputFormats.MYFORMAT]
mediaType = "text/html"
isPlainText = true
Defensive patterns

Strategy: validation

Validate before calling

# Lint config files for syntax before running hugo
# TOML:
python -c "import tomllib,sys; tomllib.loads(open('hugo.toml').read())" 2>&1 || echo "TOML invalid"
# YAML:
python -c "import yaml,sys; yaml.safe_load(open('config.yaml'))" 2>&1 || echo "YAML invalid"

Prevention

When it happens

Trigger: Any malformed top-level config section: a `[build]` map with wrong field types, a `[markup]` sub-map that fails mapstructure decode, an `[outputformats]` entry missing a required field, a `[mediatypes]` entry with a bad suffix. Also reached via the per-language re-decode path.

Common situations: Typo in a config key; upgrading Hugo and a config field changed type or was renamed; pasting example config from an incompatible Hugo version; TOML/YAML/JSON syntax that parses but yields wrong-typed values.

Understand the failure class

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/16cc1c1adcec91ec. Report an issue: GitHub.

Appendix: source

Thrown at config/allconfig/allconfig.go:1218

			} else {
				logger.Warnf("Skip unknown config key %q", key)
			}
		}
	}

	// Sort them to get the dependency order right.
	sort.Slice(decoderSetups, func(i, j int) bool {
		ki, kj := decoderSetups[i], decoderSetups[j]
		if ki.weight == kj.weight {
			return ki.key < kj.key
		}
		return ki.weight < kj.weight
	})

	for _, v := range decoderSetups {
		p := decodeConfig{p: p, c: target, fs: fs, bcfg: bcfg, logger: logger}
		if err := v.decode(v, p); err != nil {
			return fmt.Errorf("failed to decode %q: %w", v.key, err)
		}
	}

	return nil
}

func createDefaultOutputFormats(allFormats output.Formats) map[string][]string {
	if len(allFormats) == 0 {
		panic("no output formats")
	}
	rssOut, rssFound := allFormats.GetByName(output.RSSFormat.Name)
	htmlOut, _ := allFormats.GetByName(output.HTMLFormat.Name)

	defaultListTypes := []string{htmlOut.Name}
	if rssFound {
		defaultListTypes = append(defaultListTypes, rssOut.Name)
	}

View on GitHub (pinned to 52c9bd7908)