{"record":{"id":"b00b6d38cab7c445","repo":"knadh/listmonk","slug":"error-reading-default-i18n-language-file-s-v","errorCode":null,"errorMessage":"error reading default i18n language file: %s: %v","messagePattern":"error reading default i18n language file: (.+?): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"cmd/i18n.go","lineNumber":80,"sourceCode":"\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\n\tb, err := fs.Read(fmt.Sprintf(\"/i18n/%s.json\", def))\n\tif err != nil {\n\t\treturn nil, false, fmt.Errorf(\"error reading default i18n language file: %s: %v\", def, err)\n\t}\n\n\t// Initialize with the default language.\n\ti, err := i18n.New(b)\n\tif err != nil {\n\t\treturn nil, false, fmt.Errorf(\"error unmarshalling i18n language: %s: %v\", lang, err)\n\t}\n\n\t// Load the selected language on top of it.\n\tb, err = fs.Read(fmt.Sprintf(\"/i18n/%s.json\", lang))\n\tif err != nil {\n\t\treturn i, true, fmt.Errorf(\"error reading i18n language file: %s: %v\", lang, err)\n\t}\n\tif err := i.Load(b); err != nil {\n\t\treturn i, true, fmt.Errorf(\"error loading i18n language file: %s: %v\", lang, err)\n\t}\n\n\treturn i, true, nil","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/knadh/listmonk/blob/670c01717d48647093335cc23a6be6f4b79c3b6b/cmd/i18n.go#L62-L98","documentation":"getI18nLang initializes the i18n system by first reading the default English pack (/i18n/en.json) from the stuffbin filesystem, since other languages fall back to it. If that read fails it wraps the error with the 'en' code. A missing default pack breaks i18n initialization, though per the surrounding comment the app may log a warning instead of halting.","triggerScenarios":"initI18n or GetI18nLang → getI18nLang calls fs.Read(\"/i18n/en.json\") and the file is absent from the embedded filesystem — typically a binary built without stuffbin asset embedding, or a renamed/removed en.json in a fork.","commonSituations":"Deploying a bare `go build` binary without embedded assets; trimming i18n files and accidentally deleting en.json; renaming language files without keeping 'en' as the default.","solutions":["Rebuild with the standard build pipeline (make build) so /i18n/en.json is embedded via stuffbin.","Ensure i18n/en.json exists in the repo and is included in the packaging list.","If running from source, use `go run .` per the README so assets are packed automatically.","Keep 'en' present even when localizing — it is the required fallback default."],"exampleFix":"// before\n$ rm i18n/en.json && make build\n// after\n$ git checkout -- i18n/en.json && make build","handlingStrategy":"try-catch","validationCode":"b, err := fs.Read(\"/i18n/en.json\")\nif err != nil {\n    log.Fatal(\"default language pack missing; rebuild binary with embedded assets\")\n}","typeGuard":null,"tryCatchPattern":"i, warn, err := getI18nLang(lang, fs)\nif err != nil {\n    log.Printf(\"i18n unavailable, continuing without translations: %v\", err)\n    return nil, warn, nil // app continues, per library's non-fatal policy\n}","preventionTips":["Never delete or rename i18n/en.json — it is the mandatory fallback.","Build with make build to embed the default pack.","Include /i18n/en.json in any asset-trimming allowlist.","Add a startup health check that reads en.json from the embedded FS."],"tags":["i18n","build","embedded-assets","go"],"backgroundTag":"missing-embedded-resource","analyzedSha":"670c01717d48647093335cc23a6be6f4b79c3b6b","analyzedAt":"2026-09-01T03:39:35.452Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}