{"record":{"id":"9b62840d02630747","repo":"knadh/listmonk","slug":"error-reading-lang-file-s-v","errorCode":null,"errorMessage":"error reading lang file: %s: %v","messagePattern":"error reading lang file: (.+?): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"cmd/i18n.go","lineNumber":54,"sourceCode":"\t\treturn echo.NewHTTPError(http.StatusBadRequest, \"Unknown language.\")\n\t}\n\n\treturn c.JSON(http.StatusOK, okResp{json.RawMessage(i.JSON())})\n}\n\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","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/knadh/listmonk/blob/670c01717d48647093335cc23a6be6f4b79c3b6b/cmd/i18n.go#L36-L72","documentation":"getI18nLangList reads embedded i18n language JSON files from the stuffbin virtual filesystem. When fs.Get fails to retrieve a listed language file, it wraps the failure with the filename and underlying error. Because language files are embedded at build time, this almost always indicates a broken build/embed rather than runtime user error.","triggerScenarios":"GetServerConfig → getI18nLangList iterates the embedded /i18n/*.json list and fs.Get(l) fails — the file is missing from the binary (built without listmonk's stuffbin packing, e.g. plain `go build` without asset embedding) or the fs mount is misconfigured.","commonSituations":"Building the binary without the stuffbin embedding step so static/i18n resources are absent; deploying a partially built binary; forks adding a language file to the list without packaging it.","solutions":["Rebuild the binary using the project's build process (make build) so i18n assets are embedded via stuffbin.","If running from source, use `go run .` which handles asset embedding per the README.","Verify the binary contains the i18n files (stuffbin listing or build logs).","If you added a custom language, ensure it is included in the embedding step."],"exampleFix":"// before\n$ go build -o listmonk   # assets not embedded\n// after\n$ make build             # embeds i18n/static via stuffbin","handlingStrategy":"try-catch","validationCode":"// At deploy time: confirm assets are embedded\nout, _ := exec.Command(\"strings\", binaryPath).Output()\nif !strings.Contains(string(out), \"i18n/en.json\") {\n    log.Fatal(\"binary missing embedded i18n assets; rebuild with make build\")\n}","typeGuard":null,"tryCatchPattern":"langs, err := getI18nLangList(fs)\nif err != nil {\n    log.Fatalf(\"i18n init failed (embedded assets missing?): %v\", err)\n}","preventionTips":["Always build via make build so stuffbin embeds assets.","Never deploy a bare `go build` binary.","Use `go run .` when running from source.","Add a smoke test that lists embedded /i18n files on startup."],"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"}