gohugoio/hugo · error

language name %q is invalid: %s

Error message

language name %q is invalid: %s

What it means

Raised in LanguagesInternal.init (langs/config.go:159) when a language key fails paths.ValidateIdentifier. Language names are used as URL path segments and internal identifiers, so they must be valid identifiers (roughly letters/digits/hyphen/underscore, no spaces or reserved characters); the wrapped error explains which rule was violated.

Source

Thrown at langs/config.go:159

	}

	var (
		defaultSeen bool
		enIdx       int = -1
	)
	for k, v := range ls.LanguageConfigs {
		if !v.Disabled && slices.Contains(disabledLanguages, k) {
			// This language is disabled.
			v.Disabled = true
			ls.LanguageConfigs[k] = v
		}

		if k == "" {
			return "", errors.New("language name cannot be empty")
		}

		if err := paths.ValidateIdentifier(k); err != nil {
			return "", fmt.Errorf("language name %q is invalid: %s", k, err)
		}

		var isDefault bool
		if k == defaultContentLanguage {
			isDefault = true
			defaultSeen = true
		}

		if isDefault && v.Disabled {
			return "", fmt.Errorf("default language %q is disabled", k)
		}

		if !v.Disabled {
			ls.Sorted = append(ls.Sorted, LanguageInternal{Name: k, Default: isDefault, LanguageConfig: v})
		}
	}

	// Sort by weight if set, then by name.

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Rename the language key to a valid identifier such as `en`, `en-us`, or `zh-cn`.
  2. Put the human-readable name in `label` (formerly languageName) instead of the key.
  3. Set `languageCode` for the precise BCP47 code while keeping the key simple.

Example fix

# before
[languages."en US"]
label = "English"
# after
[languages.en-us]
label = "English"
languageCode = "en-US"
Defensive patterns

Strategy: validation

Validate before calling

import "golang.org/x/text/language"
// Validate each language key parses as a BCP 47 tag before load
for lang := range cfg.GetStringMap("languages") {
    if _, err := language.Parse(lang); err != nil {
        return fmt.Errorf("invalid language key %q: %w", lang, err)
    }
}

Type guard

func isValidLangTag(s string) bool {
    _, err := language.Parse(s)
    return err == nil
}

Try / catch

if err != nil && strings.Contains(err.Error(), "is invalid") {
    return fmt.Errorf("use a valid BCP 47 code (e.g. \"en\", \"pt-br\", \"zh-hans\") as the language key: %w", err)
}

Prevention

When it happens

Trigger: A `languages` map key containing invalid characters — spaces, slashes, dots, or other characters rejected by ValidateIdentifier, e.g. `languages."en US"` or `languages."fr/ca"`.

Common situations: Using full locale display names or BCP47 variants with unexpected punctuation as language keys, copy-paste from locale lists, or generated configs interpolating unsanitized values.

Related errors


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