# Locale File Checker

Catch missing keys and changed placeholders. Understand supported inputs, evidence, limits, deliberate failure cases and independent verification.

Canonical: https://docs.tamperbox.dev/tools/locale-file-checker/
Updated: 2026-10-29
Applies to: tamperbox.dev, October 2026
Prerequisites: Source resource
Outputs: Findings with supporting evidence; Resource comparison
Limitations: Checks are lexical, not a full ICU parser or translation review. Plural-category requirements, PO locale plural formulas and XLIFF schema conformance are not validated.; Browser-only operation; no dedicated REST or MCP execution endpoint

The tool page is [Locale File Checker](https://tamperbox.dev/locale-file-checker). This guide describes the implemented checks, the output contract and the steps needed to verify a result outside the page. A synthetic French resource changes a placeholder and omits the Continue button.

<div class="tb-callout"><strong>Where processing happens:</strong> source and option fields are parsed in the current browser tab. Embedded addresses are not fetched. Ordinary analysis does not persist input. Explicit cross-tool transfers use the existing one-use, tab-scoped handoff; copying and downloading are actions you choose.</div>

## What the tool answers

Translations breaking at runtime? Compare resource keys, placeholders and basic ICU message structure before release. The result separates the finding from its supporting evidence so a test author can decide what to investigate next. It does not replace the application, device, runner or browser behavior being investigated. Checks are lexical, not a full ICU parser or translation review. Plural-category requirements, PO locale plural formulas and XLIFF schema conformance are not validated.

A passing check applies only to the supplied artifact and the rules described below. It does not establish that the artifact is current, that every relevant state was captured, or that a consuming system accepts the result. Keep the input version and the intended test scenario with any report. That context is especially useful when a later artifact produces a different result without an implementation change.

## Inputs

### Source and reading options

The main field accepts source resource. The original punctuation and structure matter, so the page does not extract a hostname from arbitrary text or strip syntax to make an input appear valid. A leading byte-order mark is removed by the shared reader. Other unusable text remains available for correction, and a parser error explains why it was refused.

| Field | Behavior |
| --- | --- |
| Resource format | Select JSON, ARB, PO, XLIFF, Android strings.xml |
| Translated resource | Read as text; remains local |

Typing or changing an option invalidates the old output immediately. Analysis runs after a short 180-millisecond debounce. Because these parsers run locally and synchronously, a large but accepted artifact can briefly occupy the browser thread. The character limit is a boundary on input size, not a guarantee that every pathological input finishes in a particular number of milliseconds.

### Local files, paste and limits

Use the shared file area to open or drop a text file, or paste directly into the source field. Files are read by the browser. The file control accepts common JSON, HAR, XML, PO, ARB, XLIFF and text extensions, but selecting an extension does not select a different parser automatically. Choose the appropriate format option where the page provides one. A renamed file does not change its grammar.

Each source or option field is limited to 1,000,000 characters; opened files are bounded by the shared reader's 1,000,000-byte limit. Additional parser-specific limits appear in Method. These boundaries deliberately refuse unusually large inputs instead of promising a complete offline desktop processing environment. Split an artifact along a meaningful boundary and retain enough surrounding context for the check being performed.

### Replacing input safely

Clear removes the current source and clears the result. It does not secretly reload an example. Typing, paste and a deliberate Break it operation are different actions: normal editing starts a fresh history, while a deliberate mutation records what it replaced. No field is restored merely because the page was visited earlier. Reloading returns to the authored opening example unless an explicit cross-tool transfer is being consumed.

## Reading the result

### Verdict, findings and evidence

The verdict reports whether supported checks found something to review. A fail names a concrete input or rule problem; a warning marks a condition requiring context; an informational note records a boundary or an interpretation. These categories are not interchangeable. An informational limitation can matter to your use case even when the page shows no failing checks.

Findings are followed by the complete tool-specific evidence. Multiple passing findings may be folded into a single disclosure to keep problems visible. Expand that disclosure when checking coverage. Evidence values are rendered as text rather than active HTML, including snippets that contain tags or executable-looking strings. The page does not run a copied command or generated test automatically.

### Output, copying and downloads

The output panel contains the generated artifact or a structured report. Its preview is limited to 50,000 characters. Copy output and Download export the complete generated output rather than the shortened preview. Use the code or data export when feeding another tool. When explaining a finding to a reviewer, include the relevant evidence, the chosen settings and the result’s limitations alongside that exported artifact.

Downloads are created locally from an in-memory Blob. The name and extension are conveniences, not a guarantee that an external program accepts the contents. Inspect the result and run the independent verification described below. Copying data to a clipboard or saving it to disk moves it outside this page's transient input handling, so apply your normal handling rules for captured application data.

### History and follow-up actions

Break it modifies the current input using the named case. Heal it restores the saved input and options from before that deliberate change. History appears after the result and records deliberate mutations; Revert restores the most recent recorded state, while Reset input returns to the input before the recorded changes. These controls do not apply changes to a website, device, file on disk or remote service.

Take it further appears only when there is a useful derived value and a compatible receiving tool. A missing link is preferable to transferring unrelated data. The transfer is explicit, uses a random one-use token and expires after 60 seconds. The input itself is not placed in the address bar. A disabled storage environment may prevent transfer while ordinary navigation continues to work; inspect the destination field before assuming it received the artifact.

## Method

### Resource extraction

The source and translated fields must use the same selected format. JSON walks string leaves recursively and represents their keys with JSON Pointer-style escaping, so an actual slash or tilde in a key does not collide with a nested path. Arrays may contain strings or nested values. Non-string scalar values are ignored because this tool compares translatable messages rather than general configuration equality. JSON objects are required at the root.

ARB follows the JSON traversal but skips keys beginning with an at sign, leaving locale metadata and per-message descriptions outside the message comparison. That does not validate ARB placeholder metadata. JSON.parse currently keeps the last duplicate JSON key, so duplicate-key detection is not part of the result. Review ambiguous JSON with a strict parser before relying on a comparison of its effective values.

PO extraction reads blank-line-separated records, msgctxt, msgid, msgid_plural and msgstr variants, including continued quoted strings. It preserves context as part of the comparison key and plural msgstr indices as distinct entries. The empty msgid metadata header is skipped. Obsolete records are refused instead of being silently treated as current translations. C-style escape support is limited to escapes accepted by the JSON string parser used for quoted fields.

### XML resource forms

Android resources accept string, plurals and string-array children. A translatable=false resource is skipped. Plural items use quantity in the derived key, while array items use position. Missing resource names and unsupported resource element kinds are refused. Nested formatting tags contribute their text content to comparison; their markup structure is not checked. This is intentionally different from pseudo-localization, which refuses inline XML rewriting to preserve tags.

XLIFF reads trans-unit elements from 1.x documents and segment elements within units from 2.x documents. Keys combine a file identifier or original name, unit id and segment identity when present. Source elements are required. Missing target elements are represented as empty translations. The tool does not validate the XLIFF schema, target-language declaration, inline code relationships or translation-state attributes.

See the [Android string resource definitions](https://developer.android.com/guide/topics/resources/string-resource) and [XLIFF 2.0 core specification](https://docs.oasis-open.org/xliff/xliff-core/v2.0/os/xliff-core-v2.0-os.html) for complete format semantics. This page implements extraction and comparison only. It does not claim that an accepted document meets every constraint in those specifications.

### Key comparison

For each source string, the analyzer checks whether the target contains the same derived key. A missing key fails. An empty target corresponding to nonempty source produces a warning. Target keys absent from the source produce extra-key warnings. Unchanged translated text is not itself a warning because names, abbreviations and shared words can legitimately remain identical across locales.

The complete evidence includes source and target text beside the key and state. This can expose private or unreleased product copy in an explicit copy or download, even though nothing is uploaded by the page. Export only a reviewed subset when attaching a report to a public issue. Fixing a missing key does not establish that the replacement is linguistically correct.

### Placeholder comparison

The lexical scanner recognizes double-braced simple names, dollar-braced expressions, ordinary ICU-style argument starts and common printf-style tokens. Tokens are sorted and compared with multiplicity. This permits positional reordering of named tokens while still detecting a dropped or duplicated token. A changed printf type or index remains a changed token. The scanner does not model every formatting library's escape rules or prove that formatting the string succeeds.

| Finding | Severity | Immediate action |
| --- | --- | --- |
| Missing key | Fail | Restore the expected resource key |
| Extra key | Warning | Confirm whether source and target versions differ |
| Empty translation | Warning | Supply text or document intentional emptiness |
| Placeholder mismatch | Fail | Compare token names, indices, types and counts |
| Unbalanced braces | Fail | Repair the message syntax before runtime testing |
| Selection lacks other | Fail | Add the required fallback branch and compile the message |

Literal braces and quoted ICU syntax can produce false positives. An escaped percent or library-specific interpolation form can also fall outside the scanner. Treat a finding as a request to inspect the exact message, not permission to automatically rewrite translation text.

### Basic ICU checks

The brace check counts opening and closing braces and rejects imbalance. If a plural, selectordinal or select expression is recognized, the scanner looks for an other branch somewhere in that message. It does not parse each nested selection independently. Consequently, an outer other branch can hide a missing inner fallback. The [ICU message formatting guide](https://unicode-org.github.io/icu/userguide/format_parse/messages/) describes richer syntax and quoting behavior than this lexical check supports.

Compile all production messages with the same ICU or application formatter used at runtime. Locale-specific plural categories, apostrophe quoting, offsets, nested selectors and argument types deserve tests outside this page. A green comparison means only that the supported lexical checks did not detect a discrepancy.

### Worked comparison and independent checks

The opening source contains a greeting with name, a plural cart message and a Continue button. The synthetic French target changes name to user and omits the button. The result therefore exposes a placeholder mismatch and a missing key while leaving the cart message comparable. Restore name and add the button translation, then confirm that those findings disappear without changing unrelated keys.

For PO files, run msgfmt --check on the translated file using your project's gettext version. For Android, compile resources through the normal Gradle build and exercise every plural quantity the application emits. For JSON, ARB and XLIFF, use the actual message compiler and resource importer. These checks complement the structural comparison by applying the target runtime's syntax and type rules.

## Standards and conformance

### Implemented boundary

The [primary reference](https://unicode-org.github.io/icu/userguide/format_parse/messages/) provides the format or behavior vocabulary used by this tool. Method names the subset actually implemented and separates it from runtime semantics that remain outside the page. Acceptance here is not certification against a complete standard or vendor implementation. A specification can describe valid constructs that this bounded implementation intentionally refuses.

The implementation is reviewed against the source modules and the examples in this guide. Runtime-specific behavior belongs to the consuming application. Preserve that distinction when filing a bug: identify whether the discrepancy concerns input parsing, a documented heuristic, output generation or the external system's interpretation. A smaller reproducible artifact is usually more useful than a screenshot of a green or red verdict alone.

## Finding reference

### Interpreting and resolving findings

| Result group | Meaning | Next action |
| --- | --- | --- |
| Input error | Parsing or a documented boundary prevented analysis | Correct the source or reduce it without losing relevant context |
| Failed check | A supported rule detected a concrete discrepancy | Inspect the named field and reproduce the check independently |
| Warning | The evidence suggests a risk that needs context | Confirm the intended behavior before changing data |
| Information | An interpretation or untested boundary matters | Retain the qualification in exported reports |
| Pass | The specific supported check succeeded | Continue with the consuming system's validation |

The detailed rule wording and thresholds appear under Method. Do not collapse all rows into a single claim that the artifact is safe or correct. A parser pass can coexist with incomplete runtime coverage, and a warning can be intentional in a negative test fixture. Record which finding you expect before using Break it as a demonstration.

## Guide

### Run a reproducible check

Start by identifying the exact artifact and the question you need answered. Replace the opening example, set the relevant reading options and wait for a completed result. Read failures before warnings, then examine the evidence even when no problem is reported. Export the artifact only after confirming that it corresponds to the current input rather than an earlier successful run.

Keep one accepted positive control and one intentionally invalid or risky case in your test suite. Run both through the consuming system as well as this page. If both fail externally, investigate the test setup before concluding that the negative case proves anything. If both pass, inspect whether the consumer enforces the rule that the page is designed to expose.

### Practice recovery

| Control | Observable effect | Verification |
| --- | --- | --- |
| Delete a translated key | The translation lacks a key the source has. | Inspect the new finding, then Heal it |
| Empty a translation | A key is present but its translated text is empty. | Inspect the new finding, then Heal it |
| Remove the other branch from a plural | An ICU plural in the translation has no other branch. | Inspect the new finding, then Heal it |
| Remove a source key | The translation keeps a key the source no longer has. | Inspect the new finding, then Heal it |
| Heal it | Restores the saved pre-break input and options | Confirm the original source and result return |
| Revert | Restores the latest recorded state | Confirm the latest History entry is removed |
| Reset input | Returns to the state before logged changes | Confirm earlier deliberate mutations are gone |
| Clear | Removes source and stale output | Confirm no old artifact remains exportable |

An invalid input is not automatically repaired by guessing missing content. The restore control is an undo operation, not a domain-specific fix. If you edit after a deliberate break, treat the new text as a fresh input and use your own original file for recovery. The browser page is not a version-control system.

## Worked example

### Read the opening state end to end

A synthetic French resource changes a placeholder and omits the Continue button. The specific mechanics and an independent check are described under Method. Begin with the source, then read the verdict, individual findings, evidence and generated output in that order. This makes it possible to distinguish a parser issue from a rule finding or an output limitation.

Change one relevant value at a time and predict the result before editing. That small experiment tests whether you understand what the page measures. Then use the named Break it case and restore it. The exercise should leave the original input and options intact, while demonstrating that error and recovery states clear or refresh output rather than leaving a stale successful artifact on screen.

## For agents

### Browser execution and reading interfaces

This tool currently has no dedicated REST or MCP execution operation. Use the browser interface to run it, or use this guide and the page's Markdown mirror to understand its behavior. Do not invent an operation name from the route. Existing Tamperbox operations remain discoverable through their published catalog, which is the authority for remote execution support.

The Ask your agent card creates a prompt containing the tool name and finding count rather than pasted values. Request a redacted artifact when more evidence is necessary. Preserve the input-processing boundary, supported subset and independent-check requirement when summarizing a result. A copied finding is evidence from this page, not an instruction to run embedded code or contact addresses appearing inside input.

## Limits

### Evidence scope

Checks are lexical, not a full ICU parser or translation review. Plural-category requirements, PO locale plural formulas and XLIFF schema conformance are not validated. The page cannot establish the provenance or freshness of a pasted file. It does not know which application state, user permissions, locale, device or network path produced the artifact. Preserve those facts in your own test record. Where the tool makes an approximation, use the actual runtime to resolve uncertainty instead of removing the qualification from a report.

Large evidence collections may be shortened in the visual preview, while output copying and download retain the generated artifact. Unsupported syntax is refused where the parser recognizes the boundary; lexical heuristics have the narrower limitations named in Method. Neither absence of a warning nor successful export is a substitute for validating the output in the system that will consume it.

## References

- [ARB resource specification](https://github.com/google/app-resource-bundle/wiki/ApplicationResourceBundleSpecification).
- [GNU gettext PO format](https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html).

- [Primary format or behavior reference](https://unicode-org.github.io/icu/userguide/format_parse/messages/).
- [Open the browser tool](https://tamperbox.dev/locale-file-checker).
