find_orphan_keys
Report translation keys that no source code references. Nothing is deleted unless remove is set. Scans a specific layer or all layers, and also detects dynamic key patterns and uncertain matches. Scope-aware: each layer is checked only against the code of the apps that consume it (summary.scanScope shows each layer's effective scope), and keys referenced only from non-consuming apps are reported separately as misplacedUsages rather than as orphans. With remove the orphan keys are deleted from every locale file of their layer — uncertain keys and misplaced usages are never deleted, in any mode.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
layer | string | no | Layer name to scope this to (e.g., "root", "app-admin"). If omitted, every layer is included. Call discover to list the layers. |
locale | string | no | Locale code to read the translation keys from (e.g., "en", "en-US"). Defaults to the project default locale. |
remove | boolean | no | Permanently delete the orphan keys from every locale file of their layer. Default: false, which only reports them — run without it first and read the findings. Uncertain keys and misplaced usages are never deleted. |
scanDirs | string[] | no | Absolute paths of the directories to scan for source usage. Overrides scope-aware scanning: every layer is then checked against these directories alone. Example: "/home/user/my-app/apps/admin". |
excludeDirs | string[] | no | Directory names to skip when scanning source files. Example: "storybook", "tests", "node_modules". |
outputFile | string | no | Absolute path to write the full JSON output to. Only a compact summary is returned to the caller, which is what you want for a result too large to read in one piece. Example: ".i18n-reports/orphan-keys.json" |
projectDir | string | no | Absolute path to the project root. Defaults to I18N_PROJECT_DIR, then server cwd. Example: "/home/user/my-app". |
Result
| Field | Type | Description |
|---|---|---|
orphanKeys | Record<string, string[]> | Layer → keys no source code of a consuming app references. The only keys remove ever deletes. |
uncertainKeys | Record<string, string[]> | Layer → keys with ambiguous usage evidence. Never deleted, in any mode. |
misplacedUsages | object[] | Keys referenced only from apps that do not consume the owning layer. Reported instead of being called orphans, and never deleted. |
misplacedUsageNote | string | What to do about the misplaced usages. Present alongside them. |
declaredNamespaces | object[] | Every declared namespace with the keys it covers — the keys this scan will not report. Present when the config declares any. |
declaredNamespaceNote | string | How to read the declared namespaces. Present alongside them. |
dynamicKeyWarning | string | Present when dynamic key expressions were found, which is when the orphan list is a candidate list rather than a verdict. |
dynamicKeys | object[] | Dynamic key expressions found in source, with their call sites. |
unresolvedKeyWarnings | object[] | Dynamic expressions that could not be resolved to concrete keys, each with an ignore pattern that would cover it. |
candidateOnlyKeys | Record<string, string[]> | Layer → keys kept alive only by the bare-candidate net: a dotted string somewhere shares their name, but nothing a frontend calls a usage references them. Not orphans, but where dead references hide. |
candidateOnlyNote | string | How to read the candidate-only keys. Present alongside them. |
linkedNote | string | Why keys linked with @: from another message's value are not orphans. Present when any is. |
summary | object | What the scan covered and what it found. This is what comes back when the full result is diverted to a file. |
removed | Record<string, string[]> | Layer → keys deleted from every locale file of that layer. |
usages | Record<string, object[]> | Key → its references in source. Only keys with at least one reference appear. |
notFoundInCode | string[] | Requested keys with no reference anywhere in the scanned source. |
reportFile | string | Absolute path the full JSON result was written to. Read the file for the findings; the summary below is all that came back. |
Behavior Hints
A host reads these to decide whether a call needs your confirmation first.
| Hint | Value |
|---|---|
readOnlyHint | false |
destructiveHint | true |
idempotentHint | true |
openWorldHint | false |
Paired CLI Command
The same operation runs from a terminal as the-i18n-cli orphans, whose page documents its flags.