[BUG] German-language Claude Code corrupts canonical technical terminology (Gate→Zaun, Policy→Politik, Root→Wurzel), causing semantic and persistent-memory drift
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Claude Code systematically translates, renames, paraphrases, and sometimes invents variants of established technical and architectural terminology when the conversation/output language is German.
This is NOT merely a UI localization issue and NOT merely a matter of translation quality.
It directly changes the semantic identifiers Claude uses to reason about the architecture of a software project.
Observed examples from real long-running Claude Code projects:
Gate→Zaun("fence")Gates→Zäune("fences")Policy/Policies→Politik("politics")Root→Wurzel("root" literally translated as the botanical/anatomical German word)- canonical internal component/process names → newly invented German variants
- previously established architecture labels → inconsistent translated synonyms
The Root case is particularly important because this demonstrates that the problem is broader than obviously absurd translations.
In German technical prose, words such as "Wurzelverzeichnis" may sometimes be linguistically understandable as a translation of "root directory".
That is NOT the issue.
If Root is the canonical name of an architectural component, filesystem concept, process, scope, node, registry entry, or project-defined identifier, then changing Root to Wurzel is semantically destructive even if the translated word could be understood by a human.
The same applies to all canonical project terminology.
A model must distinguish between:
- ordinary natural-language prose that may be translated
- technical vocabulary
- canonical architecture terminology
- project-defined component names
- code identifiers
- filenames and directory names
- schema/property names
- process names
- state names
- memory keys and persistent concepts
Claude currently fails to preserve this distinction reliably.
The most severe observed examples are:
Gate → Zaun
In an agent architecture, a Gate is a control/validation boundary. A "Zaun" is literally a physical fence. These are not semantically interchangeable concepts.
Policy / Policies → Politik
In a software architecture, a Policy is a rule, policy object, enforcement definition, permission definition, or behavioral contract. "Politik" means politics/political policy in German and completely changes the semantic domain.
Root → Wurzel
In a software architecture, Root may identify a canonical project root, hierarchy root, root node, filesystem root, or explicitly named architecture component. Translating it creates a different identifier and breaks one-to-one terminology mapping.
The core problem is therefore not simply "bad German".
The core problem is:
CANONICAL CONCEPT A
→ Claude translates/renames it
→ Claude now represents it internally/output-wise as CONCEPT NAME B
→ the new name enters documentation, plans, memory, summaries, or agent communication
→ later Claude treats B as an established project concept
→ more aliases and translations are produced
→ the architecture vocabulary diverges from the actual architecture.
This becomes especially destructive during long-running agent work because the mistranslated or newly invented terminology does not remain conversational wording.
Claude can propagate it into:
- project documentation
- architecture documentation
- implementation plans
- task definitions
- persistent memory
- auto-memory
- external project memory files
- process descriptions
- internal labels
- proposed filenames
- directory descriptions
- rule descriptions
- hook feedback
- Sentinel feedback
- summaries
- context-compaction summaries
- subagent prompts
- subagent responses
- subsequent reasoning
- implementation decisions
Once an incorrect translated term enters persistent project state, Claude can retrieve it later as if it were a valid canonical concept.
This creates a self-reinforcing feedback loop:
- Canonical English technical term exists.
- Claude translates or renames it while communicating in German.
- The translation changes the identifier and potentially its meaning.
- Claude stores/references the translated version.
- Context is compacted or the session changes.
- The translated version survives in memory/documentation.
- Claude retrieves the translated variant.
- Claude assumes the translated term is legitimate.
- Claude creates additional synonyms or variations.
- Project terminology and architectural reasoning drift further away from the source architecture.
This is effectively persistent semantic-memory contamination.
I have extensively attempted to prevent this behavior using:
CLAUDE.mdinstructions- canonical terminology indexes
- terminology registries
- explicit glossaries
- exact-name lists
- blocklists for previously invented names
- memory definitions
- explicit "DO NOT TRANSLATE" rules
- explicit "DO NOT INVENT ALIASES" rules
- Sentinels
- hooks that inject terminology requirements immediately before operations
- filesystem names as canonical identifiers
- process names as canonical identifiers
- repeated corrections during sessions
These mechanisms can reduce individual occurrences but do not reliably solve the problem.
Claude eventually starts translating, paraphrasing, renaming, or inventing terminology again.
The issue becomes dramatically worse when Claude communicates in German while operating on a project whose technical terminology is primarily English.
Equivalent workflows performed entirely in English show substantially less terminology corruption.
This makes German-language operation unreliable for large agentic software projects.
Concrete observed transformations:
Gate→ZaunGates→ZäunePolicy/Policies→PolitikRoot→Wurzel
These are not isolated vocabulary problems. The same translation mechanism is dangerous for a large class of overloaded English software-engineering terms.
Representative examples of the same HIGH-RISK failure class (illustrative examples, not all claimed as individually observed):
Hook→HakenBranch→ZweigFork→GabelSocket→SteckdosePort→HafenThread→FadenPipeline→RohrleitungWorker→ArbeiterShell→Schale/MuschelHandle→GriffContainer→BehälterRegistry→RegistrierungController→Steuerung/KontrolleurContract→VertragSentinel→WächterValidator→PrüferCapability→FähigkeitState→ZustandScope→BereichArtifact→Artefakt
Some of these translations may be linguistically acceptable in ordinary German prose.
That is precisely why this bug is dangerous.
The problem is NOT whether a German translation exists.
The problem is that a canonical identifier MUST NOT be translated at all.
For example, suppose an architecture explicitly defines:
PolicyGateRootGateContractRegistryCapabilityRegistrySentinelWorkerPool
If Claude internally or externally starts referring to these as:
Politik-ZaunWurzel-ZaunVertragsregistrierungFähigkeitsregistrierungWächterArbeiter-Pool
then the deterministic one-to-one relationship between project terminology and model terminology has been destroyed.
This can affect reasoning even before it affects code because Claude begins reasoning about the system using vocabulary that is no longer identical to the vocabulary used by the architecture.
In an agentic system, terminology is not decoration.
Terminology is part of the system model.
What Should Happen?
Claude Code must clearly separate the user's conversational language from the project's canonical technical vocabulary.
A user must be able to communicate naturally with Claude in German without Claude translating, renaming, paraphrasing, or redefining the technical architecture of the project.
Expected behavior:
- Natural-language explanations may be written in German.
- Canonical technical terminology must remain unchanged.
- Project-defined terminology must remain unchanged.
- Architecture component names must remain unchanged.
- Code identifiers must remain unchanged.
- Filenames and directory names must remain unchanged.
- Process names must remain unchanged.
- State names must remain unchanged.
- Schema/property names must remain unchanged.
- Memory keys must remain unchanged.
- Glossary-defined terminology must remain unchanged.
- Existing terminology must always take precedence over generated synonyms.
- Claude must never invent an alternative name for an already-defined canonical concept unless explicitly requested by the user.
- Memory writes must preserve canonical terminology exactly.
- Auto-memory must preserve canonical terminology exactly.
- Context compaction must preserve canonical terminology exactly.
- Generated summaries must preserve canonical terminology exactly.
- Subagents must receive and preserve the same canonical terminology.
- Tool calls involving project-defined identifiers must use the canonical form.
- If Claude is uncertain whether a word is ordinary natural language or a technical/project identifier, it must preserve the original token.
A localized explanation may be added separately, but it must never replace the canonical token.
Correct:
Das Policy Gate blockiert Änderungen, wenn die Policy-Prüfung fehlschlägt.
Also acceptable:
Das Policy Gate (Prüfstufe für Richtlinien) blockiert Änderungen.
Incorrect:
Der Politik-Zaun blockiert Änderungen.
Correct:
Die Konfiguration wird relativ zum Root aufgelöst.
Also acceptable:
Die Konfiguration wird relativ zum Root (Projektstamm) aufgelöst.
Incorrect:
Die Konfiguration wird relativ zur Wurzel aufgelöst.
when Root is the canonical project identifier.
Claude Code should treat repository-defined terminology as protected semantic symbols rather than ordinary natural-language tokens.
A robust precedence model should be:
canonical repository terminology
>
canonical project glossary
>
existing architecture terminology
>
existing filenames / identifiers
>
generated natural-language vocabulary
The fundamental invariant should be:
USER LANGUAGE MAY CHANGE.
PROJECT SEMANTICS MUST NOT.
Claude should translate explanations, not redefine engineering vocabulary.
Error Messages/Logs
No explicit error, exception, or crash is produced.
This is a behavioral/model correctness failure.
Representative observed transformations:
Gate → Zaun
Gates → Zäune
Policy → Politik
Policies → Politik
Root → Wurzel
The failure occurs in generated text, reasoning, architecture descriptions, plans, documentation, persistent memory, summaries, and subsequent agent behavior rather than through an application error message.
This makes the issue especially difficult to detect automatically because Claude Code reports successful operation while silently changing the semantic vocabulary of the project.
Steps to Reproduce
- Create a new Claude Code project.
- Create a file named
ARCHITECTURE.mdwith the following content:
# Architecture
The following terms are CANONICAL project terminology.
Their exact spelling is part of the architecture.
NEVER translate, rename, paraphrase, localize, or create aliases for them.
Canonical terms:
- Root
- Gate
- Root Gate
- Policy
- Policy Gate
- Sentinel
- Validator
- Contract Registry
- Capability Registry
- Hook
- Worker Pool
Examples:
The Root contains the canonical system state.
The Root Gate validates mutations before they enter the Root.
The Policy Gate evaluates Policies.
The Sentinel observes violations.
The Validator performs deterministic validation.
The Contract Registry stores Contracts.
The Capability Registry stores Capabilities.
Hooks execute at predefined lifecycle points.
Worker Pool is the canonical name of the worker execution component.
- Create a
CLAUDE.mdfile containing:
Communicate with the user in German.
IMPORTANT:
All technical terminology defined in ARCHITECTURE.md is canonical.
Preserve every canonical term EXACTLY as written.
Never translate canonical terminology.
Never paraphrase canonical terminology.
Never rename canonical terminology.
Never invent synonyms or aliases.
Canonical terminology must remain unchanged in:
- conversation
- reasoning
- documentation
- planning
- memory
- summaries
- subagent communication
- implementation
- Start Claude Code using German as the conversational language.
- Ask:
"Analysiere die ARCHITECTURE.md vollständig und erkläre mir auf Deutsch,
wie Root, Root Gate, Policy Gate, Sentinel, Validator,
Contract Registry und Capability Registry zusammenarbeiten.
Verwende dabei zwingend die kanonischen Namen aus der Datei."
- Continue with:
"Erstelle jetzt einen detaillierten Implementierungsplan für diese
Architektur. Die kanonischen technischen Begriffe dürfen nicht
übersetzt oder umbenannt werden."
- Ask Claude to update architecture documentation:
"Erweitere ARCHITECTURE.md um eine Beschreibung der Datenflüsse.
Verwende ausschließlich die bereits definierten kanonischen Namen."
- Ask Claude to create or update persistent memory:
"Speichere die wichtigen Architekturinformationen für zukünftige
Sitzungen. Alle kanonischen technischen Begriffe müssen exakt
erhalten bleiben."
- Continue working in German for multiple turns.
- Ask Claude to delegate architecture analysis to one or more subagents,
if subagents are available.
- Continue until a longer context has accumulated.
- Where applicable, allow context compaction/summarization to occur.
- Continue the same architecture task after compaction.
- Inspect:
- conversational output
- plans
- documentation
- memory
- summaries
- subagent output
- generated internal terminology
- Observe whether canonical terminology is translated, paraphrased,
renamed, or replaced.
Observed real-world examples include:
Gate → Zaun
Gates → Zäune
Policy → Politik
Policies → Politik
Root → Wurzel
- Once one incorrect translated term has appeared, continue working
without manually correcting it.
- Observe whether Claude later reuses the incorrect term or creates
additional variants from it.
- Repeat the same workflow using English as the conversational language.
- Compare terminology stability between the German-language and
English-language sessions.
In my real-world testing, German-language operation causes substantially
more terminology translation and alias creation than equivalent
English-language operation.
The problem also persists despite additional safeguards including:
- terminology registries
- explicit glossaries
- canonical-name indexes
- blocklists
- CLAUDE.md rules
- repeated corrections
- Sentinels
- Hooks
- memory rules
- filesystem-derived canonical names
These mechanisms may reduce individual failures but have not reliably
prevented terminology drift during long-running German-language sessions.
Claude Model
Opus
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
1.26832.0
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
I Use macOS Claude Code Version, Native APP !
This issue has been reproduced repeatedly during real-world long-running Claude Code development rather than only in an artificial single-prompt test.
I have observed the underlying terminology instability across multiple Claude Opus generations, including previous and current Opus versions.
The affected projects use explicitly structured agent architectures with canonical component names, persistent external memory, terminology registries, validation mechanisms, Hooks, and Sentinels.
This makes terminology stability critical.
The most damaging aspect is NOT an isolated mistranslation in conversational output.
The problem is that incorrectly translated, paraphrased, or newly invented terminology can enter persistent artifacts and subsequently influence future model behavior.
Observed examples include:
Gate → Zaun
Gates → Zäune
Policy → Politik
Policies → Politik
Root → Wurzel
Once a translated variant enters:
- persistent memory
- architecture documentation
- implementation plans
- summaries
- context-compaction output
- subagent communication
it can later be retrieved as if it were legitimate project terminology.
This creates a self-reinforcing terminology drift.
I have attempted to mitigate this using multiple independent mechanisms:
- explicit canonical terminology rules
- CLAUDE.md
- terminology indexes
- canonical terminology registries
- explicit glossaries
- forbidden-alias/block lists
- Hooks
- Sentinels
- persistent memory rules
- filesystem-based canonical identifiers
- repeated corrections
- instructions injected close to execution
None of these mechanisms has made terminology preservation reliable over long-running German-language sessions.
The same architecture is substantially more stable when Claude communicates in English.
Public discussion documenting my investigation and observed examples:
Specific discussion/comment:
https://www.reddit.com/r/Anthropic/comments/1v9loii/comment/p0fb03g/
There are also independent reports from other Claude Code users describing Claude inventing its own technical/project jargon and requiring users to repeatedly ask what newly created terminology means:
There are existing German-language Claude Code model/core issues, but they describe different failure modes:
German-language model regression / malformed German output:
https://github.com/anthropics/claude-code/issues/21446
German umlaut corruption:
https://github.com/anthropics/claude-code/issues/14131
German typographic quote corruption:
https://github.com/anthropics/claude-code/issues/23208
This report is DISTINCT from those issues.
This issue is specifically about:
CANONICAL TECHNICAL TERMINOLOGY PRESERVATION
+
SEMANTIC DRIFT
+
PERSISTENT MEMORY CONTAMINATION
rather than grammar, Unicode, quotation marks, or general translation quality.
Another relevant observation is that Anthropic's own German Claude Code documentation currently translates the technical concept "root" using "Wurzel" in some places while retaining other technical terms such as Hooks and Skills in English.
Official German Claude Code glossary:
https://code.claude.com/docs/de/glossary
I am NOT claiming that documentation localization itself proves the model bug.
However, it demonstrates that German-language handling currently has no consistently enforced rule that canonical software-engineering terminology should remain untranslated.
This distinction is crucial:
A translation can be linguistically valid and STILL be technically incorrect.
For example:
Root → Wurzel
may be understandable to a German-speaking human in generic prose.
However, if Root is the canonical identifier of an architecture component, hierarchy node, system scope, directory concept, or explicitly named project element, replacing it with Wurzel destroys identifier stability.
The same is true for terms such as:
Gate
Policy
Hook
Branch
Fork
Socket
Thread
Pipeline
Registry
Controller
Contract
Capability
Sentinel
Validator
A canonical technical/project term must be treated as a semantic symbol, not as freely translatable prose.
I believe this therefore requires a terminology-preservation mechanism rather than another prompt-level instruction.
Potential implementation approaches:
- Treat repository-defined terminology as protected semantic tokens.
- Provide a project-level canonical terminology registry.
- Automatically protect identifiers found in:
- filenames
- directory names
- code identifiers
- schemas
- configuration
- architecture documentation
- explicit glossaries
- Preserve canonical terminology during:
- model generation
- memory writes
- auto-memory
- context compaction
- summaries
- subagent delegation
- Give canonical repository terminology precedence over natural-language localization.
- When uncertain whether a token is ordinary prose or a technical concept, preserve the original token.
- Allow optional localized explanations without replacing the canonical identifier.
For example:
Policy Gate (Prüfstufe für Richtlinien)
is acceptable.
Replacing the canonical identifier with:
Politik-Zaun
is not.
The required invariant is:
USER LANGUAGE MAY CHANGE.
PROJECT SEMANTICS MUST NOT.
For agentic software development, terminology is part of the system architecture and cannot safely be treated as presentation text.
3 Comments
Corroborating data from a different long-running German-language Claude Code setup, plus mechanism observations that support the "mechanism, not another instruction" conclusion.
Setup: Claude Code operated German-first over months of long-running agentic sessions (heavy subagent fan-outs, cross-session persistence). Countermeasures have been active since day one:
Result of a corpus sweep (project reports, memory files, knowledge-store fulltext) for the marker class named in this issue:
Zaun,Steckdose,Rohrleitung,Hafen,Gabel, …).Backfill-Typ-Politikandef_search-Politikas names for specific technical policies — while sibling blocks in the same corpus correctly preserve…-Policy(e.g.OPEN-Policy) and the source repo names the filesplit_policy.sql. Both forms coexist; the drift is intermittent, not systematic, which is what makes it hard to catch downstream.claim_probe,ops.run_journal,p_signatures, …). The drift lives in the prose-adjacent naming layer — note titles, compound nouns, summaries — which is precisely the layer that becomes persistent memory.Mechanism observations from the same setup that substantiate the contamination loop described above (each documented with dated incidents in our own audit corpus):
What measurably reduced frequency (mitigation, not a fix): store writes performed deliberately by the main instance with the terminology rules in active context, instead of background auto-extraction which runs without them; canonical English titles as upsert keys in ctx; and external checks — grep sweeps over generated artifacts and persisted notes for known-bad renderings, used as a gate rather than an instruction.
Practical bottom line: in a strictly user-controlled environment like ours — day-one terminology rules, self-managed persistence, auto-compaction avoided — German-language operation works well. The corpus data above is what "well" looks like: the absurd class at zero, the subtle class rare but nonzero. But every component of that control had to be built around Claude Code, not with it. As things stand, terminology preservation is effectively delegated to the user; when it fails, it is a "user error" by construction.
Which leads to the concrete ask, complementing the proposed terminology-registry direction: give users more influence over the compaction components themselves — the compaction/summarization prompts, an extractive (rather than interpretive) summary mode, source attribution in summaries, and hook points at the compaction and subagent-prompt boundaries. Terminology preservation enforced at generation, memory-write, compaction, and subagent boundaries should be a platform mechanism with an external check — not something each user has to reverse-engineer and rebuild outside the tool.
Independent data point from a long-running German-language Claude Code setup — partly confirming, partly narrowing the scope. I measured before commenting rather than adding a "+1".
Where I can confirm the underlying problem, from outside the model: the
recall→ widerrufen mistranslation I just filed in #86784 is exactly this failure mode, except it happens in Anthropic's own product strings rather than in model output. The German activity line for memory retrieval reads "Widerrufen einer Erinnerung" — revoking a memory. Same root cause you describe: an ambiguous English technical term translated without regard for which sense the domain requires. It has survived a prior report, an auto-close, and at least one edit to that very line. So the "translate the explanation, not the vocabulary" rule is not yet enforced on the product side either.Where my data does not reproduce your finding. My setup: German conversation throughout, months of daily agentic work on a home-server automation project, 114 file-based memory entries, subagents, context compaction, hooks. I grepped the whole memory corpus for your transformation list:
| Term | Hits |
|---|---|
| Zaun / Zäune, Politik, Hafen, Rohrleitung, Behälter, Arbeiter | 0 |
| Wurzel | 7 — all compound prose (Wurzelverzeichnis, Vault-Wurzel) or a
$wurzelvariable in a script that was German-named from the start || Haken | 4 — all meaning checkbox tick, never
Hook|| Zweig | 16 — all n8n workflow branches, which is correct German domain vocabulary; Git
Branchappears separately, in English |Counter-check on the English terms in the same corpus:
Monitor53 files,Token44,Container36,Repo35,Push34,Hook24,Commit18,Deploy17 — consistently untranslated, never once aliased.The difference that might matter, and it's testable: my project has no English
PascalCasearchitecture vocabulary. The self-built components carry originally German names (Prozesswächter,Riegel,Herzschlag) — they were never English, so no translation step exists to go wrong. Your corpus has a canonical English name sitting next to an everyday German word that plausibly maps onto it, and that adjacency is what appears to collapse. If that holds, the risk is not "German conversation" as such but the coexistence of a canonical English token and a near-synonymous German common word — which would also explain whyGate,PolicyandRootfail whileContainerandCommitdon't: nobody has a competing everyday German word for the latter.On your closing point — that this needs a preservation mechanism rather than another prompt-level instruction — my experience supports that strongly. Every rule in my setup that has to hold every single time failed as a
CLAUDE.mdinstruction and succeeded as a deterministic hook. Two live examples: a hook rejecting memory-index lines over a length limit, and one enforcing frontmatter on every file write. As prose instructions both were followed most of the time, which is the worst possible outcome — frequent enough to look solved, rare enough in failure to poison the corpus silently. AsPostToolUsehooks they simply hold.Concretely, that suggests something narrower and cheaper than model-level terminology preservation: a post-write check against a project glossary — on
Write/Editto memory, docs and plans, flag any string that matches a known translation of a canonical term. It doesn't require the model to remember anything, it catches exactly the persistence step you identify as the damaging one, and it's implementable today as a hook rather than as a model change. That won't fix reasoning-level drift within a session, but it does break the feedback loop at step 4 of your list, which is where the corpus contamination becomes permanent.Yeah, the problem is that the meaning in English for this programming language is different from the meaning in German, at least for how people generally use words. And that means the agent has to use the original term, namely the English term, because there is no equivalent term in German.
Anthropic should probably just enable some kind of developer mode here, answer mode, or something like that, so that the labels are understandable in everyday language for the developer and it stops coming up with weird made up words. It does not just invent things like root, it also invents German names for processes that are completely made up, where you sit there again and again reading and thinking, what does it actually mean?
And this weird, hallucinated word invention for topics and things that are there is a fixed part of Claude Code. I have now tried, without building up a vocabulary, to teach it to name things properly. It keeps getting better and better. It should just name the file names, it should name the folder names, it should name the functions, it should name the things as they are.
And what I noticed, for example, I had it produce output in English and in German as a test. Then I realized that sometimes the descriptions in English were kind of weird too. So it was not just that English was correct and German was the problem. Even in English, there were sometimes odd declarations. That means I even made corrections on the English side. I basically said, take the English correction and then produce the German from that English output. And then it got better.
So it is not only that there are translation problems from English to German. Sometimes the English declaration itself is just weird. But with English it is often the case that you can tell what it means. Like, for example, it does not mean the fence. So the tool, at an expert level in the programming area, should clearly name things the way people commonly name them in developer language.
At the very least, there should be an option to have it name things correctly. Or it should stop inventing jargon terms or made up labels for topics. I manage it sometimes, that it stops doing that. But you still have to keep asking it to rephrase and re-explain. The more you rephrase and explain, the better the model responds and the more it roughly understands what you mean. But weird words keep slipping out. Then it comes up with even more fanciful names again and again.
And that is 100 percent a system prompt from Anthropic. It says maybe it should describe things more simply or in flowing text, because right now the output I get is extremely technical. I have all kinds of file name labels in the answers. I have all kinds of function labels in there too, which I actually like more, because then I know what it is talking about. But by default, I do not think Anthropic wants the answers to be stuffed with the actual file names, the folders, the function descriptions, because to be fair, it can get a bit hard to follow.
Still, I at least know what it is talking about. Because when it tells me, yeah, it packaged the three pack and implemented it accordingly, what the hell three pack is it talking about? That was the big problem I had with it. I am getting it under control more and more, but the fact that there is no standard setting for this is just kind of pathetic for Anthropic. They are literally branding themselves as building this for developers, but the output in the chat interface is anything but professional.
Let us be honest. The language it sometimes uses is just unprofessional.