missing
Adds dotted key paths that appear in translation calls in your source tree but are absent from the JSON file you choose (by default the source locale file — the same one validate checks against).
Write target: --locale or source locale
Before writing (not --dry-run), the CLI shows a path preview (see --top / --full-list) and asks for confirmation in an interactive TTY unless you pass global --yes. In non-interactive environments (no TTY, CI, piped stdin), a real write requires --yes or the command exits with a usage error — same idea as cleanup.
| User input | Write target |
|---|---|
--locale <code> passed | locales/<code>.json under localesDir (same resolution as sync / fill). The CLI warns if this is not the source locale file: validate may still report gaps in the source locale until you align files. |
--locale omitted | The source locale file — config.source resolved (the file validate checks against). |
The scan (which keys the code references) is always the same; only the file that receives new paths changes.
Preconditions (fail fast)
Before merging, the command must have a usable filesystem target:
localesDirmust exist (resolved from config) when you need it — e.g. for--locale, or when the source locale path lives under that directory in your layout.- The output file must be writable (create parent dirs only if the product decision says so — otherwise fail with a clear error).
If the source locale file is missing when it is the chosen target, or localesDir is missing when required, exit non-zero with an actionable message — same spirit as other commands that require paths on disk. No prompts to “fix” this in v1.
i18nprune missing --yes
i18nprune missing --dry-run
i18nprune missing --dry-run --top 5
i18nprune missing --locale ja --yes
i18nprune missing --from-report report.json --yes
i18nprune validate --json > report.json && i18nprune missing --from-report report.json --yesDoes not call translation APIs. It only merges placeholder string values (default "") for missing paths.
End-to-end flow
- Load config —
source,localesDir,src,functions, optionalmissing/validatenamespaces (see Command namespaces in config). - Resolve write target — absolute path to
config.sourceorlocales/<code>.json(see table above). If the file is missing and the target may be created, start from{}. - Read that JSON and collect existing string leaf paths (nested objects that are not string leaves do not count as “present” for a dotted key).
- Scan
srcfor translation calls and extract literal key strings (same pipeline asvalidate). - Compute
toAdd— literals in code that are not yet string leaves in the target file (or intersect--from-reportwith the current scan when that flag is set). - Human mode, real write: print preview (respecting
--top/--full-list/ env / config defaults), then confirm unless--yesor non-interactive rules apply; on success, merge""at each path and write the file. --dry-run/--json— no write;--jsonprints the fullpathsarray.
Config and environment
| Mechanism | Role |
|---|---|
config.source, localesDir, src, functions | Required; define which file is updated and what counts as a translation call. |
config.missing.displayDefaultTop | Default human listing cap when --top is omitted (see Command namespaces). |
MISSING_DISPLAY_DEFAULT_TOP | Env override for that same default cap (valid positive integer). |
CI | With other rules, suppresses interactive confirmation in automation; use --yes to write. |
Invalid env values for MISSING_DISPLAY_DEFAULT_TOP are ignored (fallback to config, then 10).
How it works
- Scan the project (
src,functions) the same wayvalidatedoes. - Compute which literal keys appear in code but are not yet present in the chosen JSON file (the source locale file by default, or
locales/<locale>.jsonwhen--localeis set). - Merge those paths into that file with placeholders.
- Write the file (unless
--dry-run).
Default vs --locale
- Default (source locale file): The paths match what
validatecalls “missing” (code vs source locale JSON).--from-reportfromvalidate --jsonapplies cleanly. --locale <code>: The paths are “in code but not in this file” — they can differ fromvalidate’s list whenever the source locale and that locale are out of sync (e.g. aftermissingon source but beforesync). Prefer--from-reportwith the default target when you want a 1:1 withvalidate.
Recommended pipeline (source locale default)
When you use the default (update source locale only):
missing— source locale JSON gains keys the code references.sync— other locale files underlocalesDirmatch the source locale shape.fill— re-translate leaves in target locales that still match the source locale string (stale English-identical copies).filldoes not invent keys; it re-translates existing paths.validate— confirm code vs source locale JSON.quality/review— parity and per-locale review.
When you used --locale <code> instead, sync / fill / validate still follow the same roles: validate is defined against the source locale file, so keep that file in sync before relying on a green validate for the whole project.
Flags
missing-specific
| Flag | Role |
|---|---|
--locale <code> | Write into locales/<code>.json instead of the source locale file. Optional. Normalized like other commands (e.g. pt-br). |
--dry-run | List paths that would be added; no file write. Preview uses --top / --full-list. |
--from-report <file> | Read the missing array from a validate --json document (or compatible shape). |
--top <n> | Human listings show at most n paths. Default cap if omitted: MISSING_DISPLAY_DEFAULT_TOP env → config.missing.displayDefaultTop → 10. Ignored with --full-list. Must be a positive integer (same validation as review --top). |
--full-list | Human listings print every path (overrides --top). |
Global (same as other commands)
| Flag | Role |
|---|---|
--report-file, --report-format | Structured run report at end (when this command is wired into the report session). See Examples. |
-q / -s, --json | Verbosity and machine-readable mode; see JSON & long runs. |
--yes (global) | Skip the write confirmation and proceed (required for non-interactive writes). |
CI / --json / non-interactive
--localeis optional; if omitted, the source locale file is the target (see table above).- Global
--json: Machine-readable stdout; no confirmation prompt. Thepathsarray is always complete (not capped by--top). - Writes without a TTY: use
--yes(or--dry-runto preview only). Otherwise the command fails with a clearUSAGEmessage. - Missing paths on disk: See Preconditions — fail fast.
Troubleshooting
- Answering “No” at confirmation exits 0 with a note — the command did run; no file was changed. This is not a bug.
i18nprune missing -— a lone-is not a supported flag; pass--dry-run,--top, etc. explicitly.- Ctrl+C at the prompt exits non-zero (
User force closed the prompt with SIGINT) — expected. - After a successful write, the next run still lists the same paths: the tool only treats a key as present if it exists as a string leaf in the exact JSON file shown in the log. Check:
config.source(or--locale) points at the file your app loads, the file on disk saved (not reverted by another process), andi18nprune validate --jsonshowsmissing: []for that file. Mixed object vs string at a path can make the key look “still missing.”
Relation to other commands
| Command | Role |
|---|---|
validate | Read-only; compares code to source locale JSON and lists missing + dynamic sites. |
missing | Writes placeholders into source locale JSON by default, or into locales/<locale>.json with --locale. |
sync | Aligns non-source locale files to the source locale shape. |
fill | Re-translates string leaves in a target locale that still match the source locale value (does not add new key paths). |
generate | Builds a new target locale from the source locale via the translator — different from missing. |