A translation hard-codes a number the code is supposed to supply
The English string interpolates a limit, price or count; the translation types the value into the sentence. It renders fine and is wrong the moment the real value changes.
What you see
- •One language quotes a number that no longer matches what the application enforces.
- •Nothing is broken visually. There is no literal token on screen, so nobody reports it as an i18n bug.
- •It surfaces as a support question: the message says one limit and the product enforces another.
Why it happens
When a source string reads "the recommended limit of {sizeLimit}MB", a translator working from a rendered screenshot or a pre-filled machine translation sees a concrete number and writes it down. The placeholder disappears into a literal. The sentence is grammatical, the file is valid, and the value is now frozen at whatever it happened to be on the day it was translated.
1The interpolated value was typed into the sentence
The translation is accurate about the world at the time of writing and becomes quietly wrong when configuration changes. Nothing re-reads these strings when the limit is raised.
Twenty-three locales hard-code "10MB" where English interpolates `{sizeLimit}`. German reads "das empfohlene Limit von 10 MB"; Japanese still has the English sentence with the number baked in.
Our report — the Afrikaans instance is fixed; the rest are open →
2The source added a variable later
A string starts as a constant, then becomes configurable and gains a placeholder. Translations produced before that change keep the old literal, and the diff that introduced the variable touched only the source file.
Both import-warning strings gained `{sizeLimit}` in English while the translated files kept the fixed number, which is why the fix and the check landed together.
Find every instance
A hard-coded value looks exactly like a dropped placeholder to the checker, which is what makes it findable:
npx @shipi18n/cli@latest check ./locales -s en --severity 'missing-key=off,untranslated=off,orphan-key=off'The finding is `placeholder-missing`, and the reported translation shows the literal that replaced the token — read the value, not just the key name.
✗ de coverage 100.0% 1 error(s), 0 warning(s)
error import.file_size_limit_exceeded_warning_single_file placeholder-missing — dropped {sizeLimit}How to fix it
- 1Put the placeholder back and let the value come from the code. If the number belongs in the copy permanently, remove it from the source string too, so the two cannot disagree.
- 2When you find one, check the sibling strings: limits and prices usually appear in a small cluster of messages that were translated together.
- 3Run the check in CI so a value that becomes configurable cannot leave its translations behind.
The rules that catch this
How often this actually happens
This is the quietest failure in the scan: nothing renders wrong, the text is simply false: https://shipi18n.com/oss