knadh/listmonk · critical

error parsing lang file: %s: %v

Error message

error parsing lang file: %s: %v

What it means

After reading each embedded language file, getI18nLangList unmarshals it into i18nLangRaw; a JSON parse failure is wrapped with the filename and underlying error. This means an embedded i18n JSON file is syntactically invalid — a build/packaging content problem rather than a runtime issue.

Source

Thrown at cmd/i18n.go:59

// getI18nLangList returns the list of available i18n languages.
func getI18nLangList(fs stuffbin.FileSystem) ([]i18nLang, error) {
	list, err := fs.Glob("/i18n/*.json")
	if err != nil {
		return nil, err
	}

	// Read language JSON files from the fs.
	var out []i18nLang
	for _, l := range list {
		b, err := fs.Get(l)
		if err != nil {
			return out, fmt.Errorf("error reading lang file: %s: %v", l, err)
		}

		var r i18nLangRaw
		if err := json.Unmarshal(b.ReadBytes(), &r); err != nil {
			return out, fmt.Errorf("error parsing lang file: %s: %v", l, err)
		}

		out = append(out, i18nLang(r))
	}

	// Sort by language code.
	sort.SliceStable(out, func(i, j int) bool {
		return out[i].Code < out[j].Code
	})

	return out, nil
}

// The bool indicates whether the specified language could be loaded. If it couldn't
// be, the app shouldn't halt but throw a warning.
func getI18nLang(lang string, fs stuffbin.FileSystem) (*i18n.I18n, bool, error) {
	const def = "en"

View on GitHub (pinned to 670c01717d)

Solutions

  1. Validate the offending i18n JSON with a linter (jq . i18n/<lang>.json) and fix syntax errors.
  2. Look for merge-conflict markers (<<<<<<<) or trailing commas, then rebuild.
  3. Restore the file from upstream (git checkout -- i18n/<lang>.json) if accidentally modified.
  4. Rebuild and redeploy so the corrected file is embedded.

Example fix

// before (i18n/fr.json)
{ "_.code": "fr", "subscribers.invalidEmail": "e-mail invalide", }
// after
{ "_.code": "fr", "subscribers.invalidEmail": "e-mail invalide" }
Defensive patterns

Strategy: validation

Validate before calling

// CI check before building
for _, f := range i18nFiles {
    if err := json.Valid(mustRead(f)); !err {
        return fmt.Errorf("%s is not valid JSON: fix before build", f)
    }
}

Try / catch

langs, err := getI18nLangList(fs)
if err != nil {
    var parse bool = strings.HasPrefix(err.Error(), "error parsing lang file")
    log.Fatalf("invalid i18n JSON (%v): fix the file and rebuild", parse)
}

Prevention

When it happens

Trigger: GetServerConfig → getI18nLangList calls json.Unmarshal on the bytes of a language file and the JSON is malformed (truncated file, BOM, invalid syntax from a bad edit or merge conflict in i18n/*.json).

Common situations: Hand-editing a language JSON and leaving a trailing comma or unquoted key; merge-conflict markers accidentally committed; a custom translated file failing validation but embedded anyway.

Related errors


AI-assisted analysis of knadh/listmonk@670c01717d (2026-09-01). Data as JSON: /api/errors/fc6352ace90aef45. Report an issue: GitHub.