GetTranslated.AI
AI Translation & Automation

Why AI Translation Loses Context Between Strings (And How It Ships Confidently Wrong Translations to Your Users)

Why AI Translation Loses Context Between Strings (And How It Ships Confidently Wrong Translations to Your Users)

You ran your strings through ChatGPT or Claude. They came back grammatically fluent, the placeholders mostly survived, and everything looked fine in review. Then a German user emails you because your app just told them to "tap the male friend button" — because the LLM translated "contact" as a noun without knowing it was a verb in a menu action. This post is about the silent failure mode that placeholder checkers don't catch: lost context.


What "Context" Means in Localization (And Why LLMs Don't Have It)

A string file is a collection of fragments. Each entry in your strings.xml, Localizable.strings, or JSON file is a decontextualized piece of UI copy — a label, an action, an error message — stripped of everything that gave it meaning in the interface it came from.

A professional human translator working with a reputable agency gets more than a list of key-value pairs. They get a style guide, a glossary, screenshots, notes from previous translation rounds, and often a direct line to the developer. They carry context forward across every string in a batch. When they see Save, they know whether it's a button that saves a document, a verb in a menu, or a noun in a headline like "Your Saves." They know whether the target language requires formal address. They know what gender the subject noun is, because they translated it three strings ago.

What a one-shot LLM sees is a list of key-value pairs with zero surrounding product knowledge. It has no idea what screen these strings appear on, what UI element they're attached to, what your glossary says, or what decisions were made during the last release cycle. It fills in those gaps with statistical inference — and statistical inference is confident by default.

Consider the English string Save. In German alone, this has at least four correct translations depending on context:

Context German Translation
Button: save a file Speichern
Menu item: save for later Merken
Noun: your saves (saved items) Gespeicherte Inhalte
Financial: save money Sparen

Claude will pick one. It will be grammatically correct. It may be completely wrong for your UI. And it will not flag that ambiguity unless you specifically prompt it to — which means in a batch run of 500 strings, you'll never know it happened.


5 Real Context-Loss Failure Modes (With Before/After Examples)

1. Action vs. Noun Ambiguity

English loves words that function as both verbs and nouns. Localization hates them.

Android strings.xml:

<!-- English -->
<string name="action_contact">Contact</string>
<string name="action_book">Book</string>
<string name="action_share">Share</string>

An LLM batch-translating these into German with no additional context may produce:

<!-- German — naive LLM output -->
<string name="action_contact">Kontakt</string>  <!-- noun: "a contact" -->
<string name="action_book">Buch</string>         <!-- noun: "a book" -->
<string name="action_share">Anteil</string>      <!-- noun: "a share/portion" -->

The correct translations for button labels are verbal or imperative forms:

<!-- German — correct for button context -->
<string name="action_contact">Kontaktieren</string>
<string name="action_book">Buchen</string>
<string name="action_share">Teilen</string>

The noun translations are not wrong in isolation. They are wrong in context. No automated syntax checker will catch this.

2. Gender Agreement Across Strings

Many languages assign grammatical gender to nouns, and adjectives, articles, and pronouns must agree. When strings are translated in isolation, agreement across strings breaks.

iOS Localizable.strings — Spanish example:

/* English */
"profile_label" = "Profile";
"profile_updated_message" = "Your profile has been updated successfully.";
"profile_private_toggle" = "Private";

If the LLM translates profile as perfil (masculine) in one string but cuenta (feminine, "account") in another — which happens in batch runs without a glossary — then Private might come back as Privada (feminine agreement) in one string and Privado (masculine) in another. The result is grammatically inconsistent UI copy that a native speaker will immediately notice and that no automated check will flag.

3. Formality Drift

German, French, Japanese, Spanish, and many other languages have distinct formal and informal registers. Your product has a voice: either you address users as Sie or du in German, vous or tu in French. That decision should be consistent across every screen.

LLMs don't maintain register consistency across batch runs. They may translate one screen's strings in the formal register and another's informally — not because the model is unreliable, but because each API call is stateless. There is no memory of what was decided for the onboarding screen when the settings screen is being processed.

React Native JSON — German formality drift:

// Onboarding screen (translated in one batch)
{
  "welcome_message": "Willkommen! Legen Sie Ihr Konto an.",
  "onboarding_next": "Weiter"
}

// Settings screen (translated in a separate batch)
{
  "settings_title": "Deine Einstellungen",
  "settings_save": "Speichern"
}

Legen Sie is formal. Deine is informal. Both are fluent German. Together, they're a UX inconsistency that signals to native speakers that this app wasn't localized with care.

4. Terminology Inconsistency

Product terminology — "account," "profile," "workspace," "project," "user" — needs to be translated consistently across every string that references it. Without an injected glossary, an LLM will make independent translation decisions for each occurrence.

Japanese example — "account" across strings:

In a 200-string batch, the same concept might appear as アカウント (akaunuto, loan word), 口座 (kōza, financial account), or プロフィール (purofīru, profile) across different strings — all valid Japanese, all different choices, all creating terminology confusion in the UI.

French example — "user" across strings:

user might appear as utilisateur, usager, or membre in different strings depending on surrounding context and the model's inference. Each is a reasonable French word. None of them are interchangeable in a polished product.

This is precisely the failure mode that translation memory is designed to prevent — locking approved terminology so that once a decision is made, it applies everywhere.

5. Truncation-Invisible Errors

This one is subtle and particularly hard to catch. When an LLM translates a long string — a permissions explanation, an error message, a legal notice — it can drop a clause without producing any structural error. The output is shorter, fluent, and passes every automated check you have.

iOS Localizable.strings — truncated permissions string:

/* English */
"camera_permission_rationale" = "This app needs camera access to scan receipts and 
upload profile photos. Your images are never stored on our servers without your 
explicit consent.";

/* LLM output — German */
"camera_permission_rationale" = "Diese App benötigt Kamera-Zugriff, um Belege zu 
scannen und Profilfotos hochzuladen.";

The privacy disclosure — the part that matters legally — is gone. The translation is fluent. Your length checker may even pass it, because German text often runs shorter than equivalent English. Your placeholder checker passes it. Your syntax validator passes it. A native German speaker sees a compliant-looking permissions dialog that omits the data consent statement.

This is covered in more depth in the AI Translation Debugging Playbook, but the short version is: semantic completeness is not something any current automated check reliably measures.


Why This Gets Worse at Scale

At 200 strings across 2 languages, a bilingual reviewer has a realistic chance of catching formality drift or a bad noun-verb call. The file is small enough to read. The inconsistencies are visible.

At 2,000 strings across 10 languages, you are not reading every string. Nobody is. You are trusting that automated checks caught structural problems, a spot-check caught obvious errors, and the rest is fine. Context errors are effectively invisible at this scale until a native speaker files a support ticket or leaves a review.

The problem compounds with every release cycle if you're re-translating your entire string file each time. Each run resets context. The formality decision made correctly in v2.3 may be made incorrectly in v2.4 because the LLM has no memory of prior choices. Strings that were previously approved get re-translated with different terminology. You are not building on prior work — you are discarding it.

There's also no audit trail for semantic drift. You can diff two versions of a strings.xml and see that a string changed. You cannot diff "what changed in meaning" versus "what changed in source text." If action_delete was correctly translated as an imperative verb in one release and silently regressed to a noun in the next, your version control system will show a changed string value, not a semantic regression.

This is one of the core reasons that pasting files into ChatGPT directly — even carefully — creates compounding risk as your app grows. The pre-translation checklist for mobile localization files covers some of the structural risks, but context loss operates at a layer above file structure entirely.


What Actually Fixes Context Loss

The good news is that none of this is a fundamental limitation of AI translation — it's a limitation of how most teams set up their localization workflow. Context loss is a process problem, not a model problem.

Translation memory is the most direct fix for terminology inconsistency and formality drift. When an approved translation for a string or term already exists, it gets reused rather than re-inferred. The decision is made once by a human or a human-reviewed process, then applied consistently across all subsequent strings and all future releases. This is not just a quality mechanism — it is a cost mechanism. You are not paying to re-translate strings that haven't changed. The translation memory page covers the specifics of how this works in practice.

Injected glossaries lock product-specific terminology before the LLM ever processes a string. account → compte (not utilisateur, not membre). workspace → Arbeitsbereich (not Arbeitsraum, not Bereich). The glossary is applied as a constraint, not a suggestion. This eliminates the terminology inconsistency failure mode almost entirely.

String metadata and developer comments give the LLM the context a human translator would have. Key name, screen name, UI element type, and a plain-language note from the developer are sent alongside the string value. The difference in output quality between:

"action_contact" = "Contact"

and:

Key: action_contact
Screen: User profile
Element: Primary action button
Note: Verb — the action of initiating contact with another user
Value: "Contact"

is substantial. The second prompt produces the correct imperative verb form in most languages. The first is a coin flip.

Human review routing should be targeted, not applied uniformly. Strings where formality or gender agreement is required, strings flagged as low-confidence by the translation pipeline, and strings in legally or product-critically sensitive categories (privacy disclosures, payment flows, permission rationale) should route to a native speaker reviewer. Blanket human review of every string at scale is not viable; strategic routing of flagged strings is.

Continuous localization — translating only the strings that changed in each release — preserves the context decisions that have accumulated over time. Instead of re-processing your entire string file and discarding all prior approved translations, you process diffs. Strings that were correctly translated in a prior release stay translated. New strings get translated with the benefit of the existing glossary and translation memory. Context accumulates rather than resets.

These aren't speculative approaches. They are the architecture that safe AI translation workflows are built on, and they exist precisely because the failure modes described in this post are well-documented at production scale. The broader set of AI translation problems they address goes beyond context loss, but context is the category that most pure-AI-pipeline approaches get wrong first.


Takeaway

AI translation is fast. That's real and it matters. A model that can process 500 strings in seconds is genuinely useful for teams that ship frequently to global markets.

But speed without context is how you get a German user emailing you about the male friend button. The model was fast. The model was confident. The model was wrong in a way that no automated check caught, because the check was looking at structure and the error was semantic.

The fix is not to stop using AI for translation. The fix is to stop treating localization as a stateless batch job. Context — glossaries, translation memory, string metadata, formality decisions, prior approved translations — needs to travel with your strings on every run, not get discarded and rebuilt from scratch each time.

Fast and accurate are not in conflict. But they require a workflow that carries context forward, not one that starts from zero on every release.

Ready to localize your app?

Get started free — no credit card required.

Start Translating →