gohugoio/hugo · error

failed to decode languages config: %w

Error message

failed to decode languages config: %w

What it means

Emitted by the 'languages' entry of Hugo's config decoder table when langs.DecodeConfig cannot turn the [languages] config section into valid language definitions. It wraps the underlying validation error, e.g. an invalid defaultContentLanguage, a malformed language key, or inconsistent per-language settings, so the site build stops before an inconsistent multilingual setup is used.

Source

Thrown at config/allconfig/alldecoders.go:252

		},
	},
	"languages": {
		key: "languages",
		decode: func(d decodeWeight, p decodeConfig) error {
			m := hmaps.CleanConfigStringMap(p.p.GetStringMap(d.key))
			// Root-level locale/languageCode is passed to DecodeConfig so it can
			// be applied to the default content language inside langs.DecodeConfig.
			// They are passed separately so that an explicit per-lang languageCode
			// can override a root-level languageCode (but not a root-level locale).
			rootLocale := p.p.GetString("locale")
			rootLanguageCode := p.p.GetString("languagecode")
			var (
				err                    error
				defaultContentLanguage string
			)
			p.c.Languages, defaultContentLanguage, err = langs.DecodeConfig(p.c.RootConfig.DefaultContentLanguage, rootLocale, rootLanguageCode, p.c.RootConfig.DisableLanguages, m)
			if err != nil {
				return fmt.Errorf("failed to decode languages config: %w", err)
			}
			for k, v := range p.c.Languages.Config.LanguageConfigs {
				if v.Disabled {
					p.c.RootConfig.DisableLanguages = append(p.c.RootConfig.DisableLanguages, k)
				}
			}

			p.c.RootConfig.DisableLanguages = hstrings.UniqueStringsReuse(p.c.RootConfig.DisableLanguages)
			sort.Strings(p.c.RootConfig.DisableLanguages)
			p.c.RootConfig.DefaultContentLanguage = defaultContentLanguage
			return nil
		},
	},
	"versions": {
		key: "versions",
		decode: func(d decodeWeight, p decodeConfig) error {
			var err error
			m := hmaps.CleanConfigStringMap(p.p.GetStringMap(d.key))

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Ensure defaultContentLanguage matches one of the keys defined under [languages] exactly.
  2. Check that every [languages.<key>] block is a table/map with valid fields (languageName, weight, contentDir, ...), not a scalar.
  3. Read the wrapped inner error text — it names the specific offending key or value.
  4. Validate the config file syntax (TOML/YAML) if the section parses into an unexpected shape.

Example fix

# before
defaultContentLanguage = 'en-us'
[languages.en]
languageName = 'English'
# after
defaultContentLanguage = 'en'
[languages.en]
languageName = 'English'
Defensive patterns

Strategy: validation

Validate before calling

// Sanity-check the languages map shape before loading
langs, ok := cfg.Get("languages").(map[string]any)
if !ok {
    return errors.New("languages must be a map of langCode -> settings")
}
for code, v := range langs {
    if _, ok := v.(map[string]any); !ok {
        return fmt.Errorf("languages.%s must be a table, got %T", code, v)
    }
}

Try / catch

conf, err := allconfig.LoadConfig(opts)
if err != nil {
    var fe herrors.FileError
    if errors.As(err, &fe) {
        // surface filename:line:col from the config file to the user
    }
    return err
}

Prevention

When it happens

Trigger: A [languages] map in hugo.toml/config.toml whose keys or values langs.DecodeConfig rejects: defaultContentLanguage set to a language not defined under [languages], invalid language keys (bad BCP-47-ish tags), non-map values under a language key, or conflicting root-level languageCode/locale versus per-language settings.

Common situations: Adding a second language to a previously monolingual site and forgetting to define the defaultContentLanguage under [languages]; typos like [languages.en] vs defaultContentLanguage = 'en-us'; YAML/TOML indentation errors that turn a language block into a scalar; upgrading Hugo versions where language config validation tightened.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/3580bb4e31908e5c.json. Report an issue: GitHub ↗.