{"record":{"id":"fc6352ace90aef45","repo":"knadh/listmonk","slug":"error-parsing-lang-file-s-v","errorCode":null,"errorMessage":"error parsing lang file: %s: %v","messagePattern":"error parsing lang file: (.+?): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"cmd/i18n.go","lineNumber":59,"sourceCode":"\n// getI18nLangList returns the list of available i18n languages.\nfunc getI18nLangList(fs stuffbin.FileSystem) ([]i18nLang, error) {\n\tlist, err := fs.Glob(\"/i18n/*.json\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Read language JSON files from the fs.\n\tvar out []i18nLang\n\tfor _, l := range list {\n\t\tb, err := fs.Get(l)\n\t\tif err != nil {\n\t\t\treturn out, fmt.Errorf(\"error reading lang file: %s: %v\", l, err)\n\t\t}\n\n\t\tvar r i18nLangRaw\n\t\tif err := json.Unmarshal(b.ReadBytes(), &r); err != nil {\n\t\t\treturn out, fmt.Errorf(\"error parsing lang file: %s: %v\", l, err)\n\t\t}\n\n\t\tout = append(out, i18nLang(r))\n\t}\n\n\t// Sort by language code.\n\tsort.SliceStable(out, func(i, j int) bool {\n\t\treturn out[i].Code < out[j].Code\n\t})\n\n\treturn out, nil\n}\n\n// The bool indicates whether the specified language could be loaded. If it couldn't\n// be, the app shouldn't halt but throw a warning.\nfunc getI18nLang(lang string, fs stuffbin.FileSystem) (*i18n.I18n, bool, error) {\n\tconst def = \"en\"\n","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/knadh/listmonk/blob/670c01717d48647093335cc23a6be6f4b79c3b6b/cmd/i18n.go#L41-L77","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Validate the offending i18n JSON with a linter (jq . i18n/<lang>.json) and fix syntax errors.","Look for merge-conflict markers (<<<<<<<) or trailing commas, then rebuild.","Restore the file from upstream (git checkout -- i18n/<lang>.json) if accidentally modified.","Rebuild and redeploy so the corrected file is embedded."],"exampleFix":"// before (i18n/fr.json)\n{ \"_.code\": \"fr\", \"subscribers.invalidEmail\": \"e-mail invalide\", }\n// after\n{ \"_.code\": \"fr\", \"subscribers.invalidEmail\": \"e-mail invalide\" }","handlingStrategy":"validation","validationCode":"// CI check before building\nfor _, f := range i18nFiles {\n    if err := json.Valid(mustRead(f)); !err {\n        return fmt.Errorf(\"%s is not valid JSON: fix before build\", f)\n    }\n}","typeGuard":null,"tryCatchPattern":"langs, err := getI18nLangList(fs)\nif err != nil {\n    var parse bool = strings.HasPrefix(err.Error(), \"error parsing lang file\")\n    log.Fatalf(\"invalid i18n JSON (%v): fix the file and rebuild\", parse)\n}","preventionTips":["Run jq/python json.tool over i18n/*.json in CI.","Grep for merge-conflict markers before committing translations.","Never hand-edit JSON without re-validating.","Fail the build on invalid language files."],"tags":["i18n","json","parsing","go"],"backgroundTag":"json-parse-failed","analyzedSha":"670c01717d48647093335cc23a6be6f4b79c3b6b","analyzedAt":"2026-09-01T03:39:35.452Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}