CW
Navigation

Language

πŸ‡§πŸ‡· PT πŸ‡ΊπŸ‡Έ EN

Navigation

Home About Stack Companies Blog TOOLS
CONTACT
Back to Blog
21 May 2026 288 Views
The End of Silent Localization Errors in .NET Apps - Meet resx-lint

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.

https://github.com/CW-Software-Apps/resx-lint

Features

  • Static analysis β€” scans {maui:Translate Key} in XAML and AppResources.Key in C# and reports missing keys as build errors
  • Auto-fixes β€” removes duplicate keys, adds missing Designer.cs properties, 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-if mode β€” preview every change without touching any file
  • CI-friendly β€” --fail-on-warnings escalates 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
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 &quot;$(MSBuildProjectDirectory)&quot; --resx-file &quot;$(MSBuildProjectDirectory)\Resources\AppResources.resx&quot;"
    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

Cezar Wagenheimer
Written By

Cezar Wagenheimer

Full Stack Developer & Game Creator. Specialized in building immersive digital experiences and advanced systems.

Connect:
Share this article

Related reads

Explore by topic

Comments

Be the first to comment!

Leave a comment