placeholder-missing: placeholder dropped from a translation
error — fails the build
A placeholder that exists in the source string — {{name}}, {count}, %s, %1$s, %@, a $t() reference or an inline HTML tag — is gone from the translation. At runtime this renders a sentence missing its subject or number, throws, or prints the literal placeholder to the user.
What triggers it
// en.json
{ "greeting": "Hello {{name}}, you have {{count}} messages" }
// es.json
{ "greeting": "Hola, tienes mensajes" } // both placeholders goneFixed
// es.json
{ "greeting": "Hola {{name}}, tienes {{count}} mensajes" }Why it matters
Placeholder drift is the #1 silent i18n failure: every key is present, the file is valid JSON, and the check that only diffs key sets passes it. Eight placeholder syntaxes are recognised, and reordering positional printf (%1$s, %2$s) is legal while deletion is not.
How to fix it
Restore the placeholder in the translation — its name must match the source exactly. Retranslating the key with shipi18n translate validates every placeholder on the way back in.
How to silence it
--ignore-keys 'path.to.key' for a string where the drop is deliberate.
Check for this in CI
npx @shipi18n/cli check ./locales -s en
# SARIF for inline PR annotations:
npx @shipi18n/cli check ./locales -s en -r sarif -o shipi18n.sarifThe structural checks need no API key. Findings of this rule link back to this page from the SARIF helpUri.
Related rules
- placeholder-added — placeholder invented by a translation
- plural-forms — plural forms lost in translation