A Flutter string renders without its placeholder
An .arb translation drops a placeholder the English string defines, so the generated localizations return a sentence with the value missing. What causes it and how to check every .arb file you ship.
What you see
- •An error message, counter or title renders without the value it was supposed to include, in one locale.
- •`flutter gen-l10n` completes without complaint, because the key and its metadata are present.
- •The affected string is often a plural or an error path, which is exactly where nobody looks during review.
Why it happens
An .arb file pairs each message with a `@key` block that declares its placeholders. The generator wires those declarations into a typed method, but it does not verify that each translation actually uses them. A translation that drops `{error}` or `{count}` still compiles, still type-checks at the call site, and renders a sentence missing its subject.
1The placeholder is dropped from the translated message
Most common in error strings, where the translation reads as a generic apology instead of naming what failed. The user loses the only diagnostic they had.
KRTirtho/spotube35k★
The Korean `error` string dropped `{error}`, so the app could report that something failed but never what.
2A title or label loses the name it was describing
A screen heading or toast loses `{title}` or `{name}` and becomes a generic label, so several distinct messages collapse into the same text.
German, Spanish, Japanese and Korean each dropped `{title}` or `{name}` from playback strings.
3A plural form loses the count
ICU plural branches are separate pieces of text, so one branch can lose `{count}` while the others keep it. The bug only appears at the quantity that selects the broken branch.
Anxcye/anx-reader8.9k★
Traditional Chinese rendered the "yesterday" statistic without `{count}`, while the simplified Chinese form kept it.
Find every instance
Point the checker at the directory holding your .arb files:
npx @shipi18n/cli@latest check ./lib/l10n -s en --severity 'missing-key=off,untranslated=off,orphan-key=off'The ARB grammar reads placeholders through the ICU parser, so arguments nested inside plural and select branches are counted, and `%{x}` sequences inside ARB text are not mistaken for placeholders.
✗ ko coverage 100.0% 1 error(s), 0 warning(s)
error error placeholder-missing — dropped {error}How to fix it
- 1Restore the placeholder in the translated message using the exact name from the `@key` metadata.
- 2Check every plural branch, not just the one that was reported: `one` and `other` are separate strings and fail independently.
- 3Run the check in CI ahead of `gen-l10n`, so a translation that drops a declared placeholder fails the pull request.
The rules that catch this
How often this actually happens
Flutter projects in our scan were hand-maintained and generally accepted fixes quickly: https://shipi18n.com/oss