The End of Silent Localization Errors in .NET Apps - Meet resx-lint
"Stop silent localization errors in .NET apps. resx-lint validates .resx keys in XAML and C#, auto-fixes errors, and integrates into your build pipeline."
resx-lint is a .NET global tool that validates .resx localization keys against your XAML and C# source files. It catches missing keys before they reach production, auto-fixes common problems, and integrates directly into your build pipeline so errors appear inline in Visual Studio, Rider, and any CI output.
Features
- Static analysis β scans
{maui:Translate Key}in XAML andAppResources.Keyin C# and reports missing keys as build errors - Auto-fixes β removes duplicate keys, adds missing
Designer.csproperties, and backfills orphaned language entries automatically - MSBuild-native errors β emits
file(line): error TRANS001: ...format so VS/Rider show inline squiggles with clickable links - Similar key suggestions β when a key is missing, suggests the closest matches to help spot typos quickly
--what-ifmode β preview every change without touching any file- CI-friendly β
--fail-on-warningsescalates warnings to errors for stricter pipelines - Zero dependencies β single self-contained executable, no extra NuGet packages required
Installation
Global (local dev)
dotnet tool install --global ResxLint
Per-repo (recommended for teams and CI)
dotnet new tool-manifest # creates .config/dotnet-tools.json β commit this file
dotnet tool install ResxLint
New devs and CI agents just run once:
dotnet tool restore
Usage
resx-lint --project-dir <dir> --resx-file <path> [options]
| Option | Description |
|---|---|
--project-dir <dir> |
Root of the project (where .xaml and .cs files live) |
--resx-file <path> |
Path to the base .resx file (e.g. Resources/AppResources.resx) |
--what-if |
Preview all changes without writing any files |
--fail-on-warnings |
Treat TRANS006 and TRANS007 as fatal errors |
--quiet |
Suppress β OK and βΉ INFO messages β only show problems |
--help |
Show help and exit |
MSBuild Integration
Drop this target into your .csproj to validate on every build.
The snippet below checks whether resx-lint is installed before running it and emits a clear, actionable error message if it is not β instead of the cryptic exited with code 9009 you'd get otherwise:
<Target Name="ValidateTranslationKeys" BeforeTargets="BeforeBuild">
<!-- Friendly error if resx-lint is not installed -->
<Exec Command="resx-lint --help"
ConsoleToMSBuild="true"
IgnoreExitCode="true"
StandardOutputImportance="low"
StandardErrorImportance="low">
<Output TaskParameter="ExitCode" PropertyName="_ResxLintExitCode" />
</Exec>
<Error
Condition="'$(_ResxLintExitCode)' == '9009' OR '$(_ResxLintExitCode)' == '127'"
Text="resx-lint is not installed. Run: dotnet tool install --global ResxLint | Docs: https://github.com/CW-Software-Apps/resx-lint" />
<!-- Run validation -->
<Exec
Command="resx-lint --project-dir "$(MSBuildProjectDirectory)" --resx-file "$(MSBuildProjectDirectory)\Resources\AppResources.resx""
ConsoleToMSBuild="true"
IgnoreExitCode="false" />
</Target>
If the tool is missing, the build stops with:
error : resx-lint is not installed. Run: dotnet tool install --global ResxLint
Docs: https://github.com/CW-Software-Apps/resx-lint
For strict mode (warnings become errors), add --fail-on-warnings to the Exec command.
CI/CD Integration
GitHub Actions
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.x'
- name: Restore tools
run: dotnet tool restore # reads .config/dotnet-tools.json
- name: Validate translations
run: resx-lint --project-dir . --resx-file Resources/AppResources.resx --fail-on-warnings
Docker / Coolify / Self-hosted
If your CI/CD builds via Docker (e.g. Coolify on Hostinger), install the tool in your Dockerfile and run it before dotnet publish:
# Install resx-lint
RUN dotnet tool install --global ResxLint
ENV PATH="${PATH}:/root/.dotnet/tools"
# Copy sources
COPY [".", "/src/app"]
# β
Validate translations β fails the Docker build if keys are missing
RUN resx-lint \
--project-dir /src/app \
--resx-file /src/YourLibrary/Resources/AppResources.resx
# Build
RUN dotnet publish MyApp.csproj -f net10.0-android -c Release
The tool exits with code 3 on fatal errors, which causes the Docker build to fail and stops the Coolify deployment before a broken build reaches production.
Diagnostic Codes
| Code | Severity | Description | Action |
|---|---|---|---|
TRANS001 |
β Fatal | Key used in {maui:Translate Key} (XAML) not found in base .resx |
Fix manually |
TRANS002 |
π§ Auto-fix | Duplicate key found in a .resx file |
Extra occurrences removed |
TRANS003 |
π§ Auto-fix | Key in base .resx has no corresponding property in Designer.cs |
Property added automatically |
TRANS004 |
β Fatal | Key accessed as AppResources.Key (C#) not found in base .resx |
Fix manually |
TRANS005 |
π§ Auto-fix | Key exists in a language file but not in the base .resx |
Added to base with [TRADUZIR] placeholder |
TRANS006 |
β οΈ Warning | Key in base .resx has no translation in one or more language files |
Add translation or escalate with --fail-on-warnings |
TRANS007 |
β οΈ Warning | Base .resx value is empty or a placeholder like [TRADUZIR] |
Translation pending |
TRANS008 |
βΉοΈ Info | Value is identical to the base language in a translated file | May be intentional (proper nouns, numbers, etc.) |
Fatal errors (TRANS001, TRANS004) stop the build immediately. Auto-fixes (TRANS002, TRANS003, TRANS005) modify files and return exit code 1 so MSBuild restarts the build to re-validate.
Exit Codes
| Code | Meaning |
|---|---|
0 |
All OK β no issues found |
1 |
Auto-fixes were applied β restart the build to re-validate |
2 |
Invalid parameters |
3 |
Fatal errors found (TRANS001 or TRANS004) |
Output Sample
βββ 4/6 Validating XAML usage ({maui:Translate}) βββ
Views/HomePage.xaml(42) : error TRANS001 : Translation key 'WelcomeTitel' not found in AppResources.resx. Similar keys: 'WelcomeTitle'.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
SUMMARY β resx-lint
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
.resx base : Resources\AppResources.resx
Keys in base : 312
Languages : 2 (AppResources.en-US.resx, AppResources.es-ES.resx)
Auto-fixes applied : 0
Warnings : 0
Fatal errors : 1
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Build cancelled: 1 fatal error(s). Fix the missing keys and rebuild.
Requirements
- .NET 10 SDK or later
License
MIT Β© CW Software
