Summary
@salesforce/plugin-trust declares a bin entry that points at a file it does not publish:
"bin": { "sf-trust": "bin/dev" }
The published tarball contains bin/dev.js, bin/dev.cmd, bin/run.js and bin/run.cmd — there is no extensionless bin/dev. Confirmed in @salesforce/plugin-trust@4.0.9 (bundled with @salesforce/cli@2.149.9) and @salesforce/plugin-trust@4.0.11 (bundled with the current latest @salesforce/cli@2.150.6).
Because the bin target doesn't resolve, npm's bin-links silently skips it (link-gently.js, "if the script or manpage isn't there, just ignore it"), so node_modules/@salesforce/cli/node_modules/.bin/sf-trust is never created — not even by a clean install.
On its own that would be a harmless cosmetic bug. In practice it permanently breaks npm install for every project that depends on @salesforce/cli, because it trips a latent npm/arborist bug:
- arborist's
getAction classifies a node as CHANGE when any of its declared bins is missing from disk, so plugin-trust is CHANGE on every install forever, despite matching version and integrity.
- That
CHANGE node lives inside @salesforce/cli's npm-shrinkwrap.json subtree, which arborist only diffs after it has already decided which directories to move aside for rollback. The node therefore has no rollback entry, and npm install crashes with ERR_INVALID_ARG_TYPE: The "from" argument must be of type string. Received undefined.
- The crash happens before the step that creates bin links, so the missing link can never get created and every subsequent install fails identically.
I've filed the npm-side analysis at npm/cli#4907 (an open issue since 2022 that nobody had root-caused). npm should certainly fix its end — but @salesforce/cli is currently the trigger that makes it fire for everyone, and the fix on this side is a one-line change.
Suggested fix: point the bin at the published production entry point rather than the ts-node development one:
"bin": { "sf-trust": "bin/run.js" }
bin/dev.js has the shebang #!/usr/bin/env -S node --loader ts-node/esm and is not usable from a published package anyway (ts-node isn't a runtime dependency). bin/run.js is the correct entry. Alternatively, if sf-trust isn't meant to be a user-facing executable at all, drop the bin field.
Steps To Reproduce
A dedicated repo isn't needed — this reproduces from a two-line package.json with no Salesforce project or org involved, since the failure happens at npm install time. Verified on the latest @salesforce/cli@2.150.6 against the public npm registry.
mkdir sf-bin-repro && cd sf-bin-repro
cat > package.json <<'EOF'
{ "name": "sf-bin-repro", "version": "1.0.0", "private": true,
"devDependencies": { "@salesforce/cli": "2.150.6", "lint-staged": "17.4.1" } }
EOF
# 1. clean install — succeeds
npm install
# 2. the declared bin was never linked
ls -la node_modules/@salesforce/cli/node_modules/.bin/sf-trust
# 3. now update any unrelated dependency, with node_modules still in place
npm i -D lint-staged@17.5.0
To see the packaging bug in isolation, without any npm interaction:
npm pack @salesforce/plugin-trust@4.0.11
tar tzf salesforce-plugin-trust-4.0.11.tgz | grep '^package/bin/'
# package/bin/dev.cmd
# package/bin/dev.js
# package/bin/run.cmd
# package/bin/run.js <-- no extensionless "bin/dev"
npm view @salesforce/plugin-trust@4.0.11 bin
# { 'sf-trust': 'bin/dev' }
Expected result
node_modules/@salesforce/cli/node_modules/.bin/sf-trust exists after installation, pointing at a file that is actually published.
- Step 3 completes normally.
Actual result
Step 2:
ls: node_modules/@salesforce/cli/node_modules/.bin/sf-trust: No such file or directory
Step 3:
npm error code ERR_INVALID_ARG_TYPE
npm error The "from" argument must be of type string. Received undefined
Every subsequent npm install in that project fails the same way until node_modules is deleted entirely — and it starts failing again as soon as the tree is reinstalled, because the bin link is still never created.
A retry after the first crash produces a second, different failure, because npm's failed rollback leaves its staging directories behind:
npm error code ENOTEMPTY
npm error syscall rename
npm error path .../node_modules/lint-staged
npm error dest .../node_modules/.lint-staged-gfX1MQHW
Additional information
Verified that this is the sole cause of the install failure: creating the missing link by hand makes the node compare equal and the install succeed immediately, with no other change.
P=node_modules/@salesforce/cli/node_modules/@salesforce/plugin-trust
printf '#!/usr/bin/env node\n' > "$P/bin/dev" && chmod +x "$P/bin/dev"
ln -sfn ../@salesforce/plugin-trust/bin/dev \
node_modules/@salesforce/cli/node_modules/.bin/sf-trust
npm i -D lint-staged
# added 1 package, changed 163 packages, and audited 2563 packages in 10s
Measured with arborist's own diffing API before and after that change:
before: never-retired orphan nodes: 91, orphans that trigger the crash: 1 (@salesforce/plugin-trust)
after : never-retired orphan nodes: 90, orphans that trigger the crash: 0
Note on the issue template: sf doctor isn't applicable here — the CLI itself runs fine, and the failure is in npm install of a project that depends on @salesforce/cli, before any sf command is involved.
System Information
Shell: zsh on macOS (Darwin 25.6.0, arm64), Node v22.22.3, npm 10.9.8.
The project below pins @salesforce/cli@2.149.9, but as noted above the packaging bug and the resulting install failure are both confirmed on the current latest, 2.150.6.
{
"architecture": "darwin-arm64",
"cliVersion": "@salesforce/cli/2.149.9",
"nodeVersion": "node-v22.22.3",
"osVersion": "Darwin 25.6.0",
"rootPath": "/Users/…/node_modules/@salesforce/cli",
"shell": "zsh",
"pluginVersions": [
"@oclif/plugin-autocomplete 3.2.56 (core)",
"@oclif/plugin-commands 4.1.63 (core)",
"@oclif/plugin-help 6.2.58 (core)",
"@oclif/plugin-not-found 3.2.93 (core)",
"@oclif/plugin-plugins 5.4.87 (core)",
"@oclif/plugin-search 1.2.54 (core)",
"@oclif/plugin-update 4.7.59 (core)",
"@oclif/plugin-version 2.2.57 (core)",
"@oclif/plugin-warn-if-update-available 3.1.73 (core)",
"@oclif/plugin-which 3.2.61 (core)",
"@salesforce/cli 2.149.9 (core)",
"agent 2.0.3 (core)",
"apex 4.1.0 (core)",
"api 2.0.9 (core)",
"auth 5.0.6 (core)",
"code-analyzer 5.0.0 (user) published 495 days ago (Tue Apr 29 2025) (latest is 5.16.0)",
"data 5.1.5 (core)",
"deploy-retrieve 4.1.2 (core)",
"info 4.0.9 (core)",
"lightning-dev 3.5.1 (user) published 375 days ago (Wed Aug 27 2025) (latest is 6.2.18)",
"limits 4.0.3 (core)",
"marketplace 2.0.5 (core)",
"org 6.0.9 (core)",
"packaging 3.0.5 (core)",
"schema 4.0.5 (core)",
"settings 3.0.5 (core)",
"sobject 2.0.5 (core)",
"telemetry 4.0.5 (core)",
"templates 57.0.9 (core)",
"trust 4.0.9 (core)",
"ui-bundle-dev 1.2.2 (user) published 159 days ago (Tue Mar 31 2026) (latest is 1.2.4)",
"user 5.0.1 (core)"
]
}
Summary
@salesforce/plugin-trustdeclares abinentry that points at a file it does not publish:The published tarball contains
bin/dev.js,bin/dev.cmd,bin/run.jsandbin/run.cmd— there is no extensionlessbin/dev. Confirmed in@salesforce/plugin-trust@4.0.9(bundled with@salesforce/cli@2.149.9) and@salesforce/plugin-trust@4.0.11(bundled with the current latest@salesforce/cli@2.150.6).Because the bin target doesn't resolve, npm's
bin-linkssilently skips it (link-gently.js, "if the script or manpage isn't there, just ignore it"), sonode_modules/@salesforce/cli/node_modules/.bin/sf-trustis never created — not even by a clean install.On its own that would be a harmless cosmetic bug. In practice it permanently breaks
npm installfor every project that depends on@salesforce/cli, because it trips a latent npm/arborist bug:getActionclassifies a node asCHANGEwhen any of its declared bins is missing from disk, soplugin-trustisCHANGEon every install forever, despite matching version and integrity.CHANGEnode lives inside@salesforce/cli'snpm-shrinkwrap.jsonsubtree, which arborist only diffs after it has already decided which directories to move aside for rollback. The node therefore has no rollback entry, andnpm installcrashes withERR_INVALID_ARG_TYPE: The "from" argument must be of type string. Received undefined.I've filed the npm-side analysis at npm/cli#4907 (an open issue since 2022 that nobody had root-caused). npm should certainly fix its end — but
@salesforce/cliis currently the trigger that makes it fire for everyone, and the fix on this side is a one-line change.Suggested fix: point the bin at the published production entry point rather than the ts-node development one:
bin/dev.jshas the shebang#!/usr/bin/env -S node --loader ts-node/esmand is not usable from a published package anyway (ts-nodeisn't a runtime dependency).bin/run.jsis the correct entry. Alternatively, ifsf-trustisn't meant to be a user-facing executable at all, drop thebinfield.Steps To Reproduce
A dedicated repo isn't needed — this reproduces from a two-line
package.jsonwith no Salesforce project or org involved, since the failure happens atnpm installtime. Verified on the latest@salesforce/cli@2.150.6against the public npm registry.To see the packaging bug in isolation, without any npm interaction:
Expected result
node_modules/@salesforce/cli/node_modules/.bin/sf-trustexists after installation, pointing at a file that is actually published.Actual result
Step 2:
Step 3:
Every subsequent
npm installin that project fails the same way untilnode_modulesis deleted entirely — and it starts failing again as soon as the tree is reinstalled, because the bin link is still never created.A retry after the first crash produces a second, different failure, because npm's failed rollback leaves its staging directories behind:
Additional information
Verified that this is the sole cause of the install failure: creating the missing link by hand makes the node compare equal and the install succeed immediately, with no other change.
Measured with arborist's own diffing API before and after that change:
Note on the issue template:
sf doctorisn't applicable here — the CLI itself runs fine, and the failure is innpm installof a project that depends on@salesforce/cli, before anysfcommand is involved.System Information
Shell:
zshon macOS (Darwin 25.6.0, arm64), Node v22.22.3, npm 10.9.8.The project below pins
@salesforce/cli@2.149.9, but as noted above the packaging bug and the resulting install failure are both confirmed on the current latest,2.150.6.{ "architecture": "darwin-arm64", "cliVersion": "@salesforce/cli/2.149.9", "nodeVersion": "node-v22.22.3", "osVersion": "Darwin 25.6.0", "rootPath": "/Users/…/node_modules/@salesforce/cli", "shell": "zsh", "pluginVersions": [ "@oclif/plugin-autocomplete 3.2.56 (core)", "@oclif/plugin-commands 4.1.63 (core)", "@oclif/plugin-help 6.2.58 (core)", "@oclif/plugin-not-found 3.2.93 (core)", "@oclif/plugin-plugins 5.4.87 (core)", "@oclif/plugin-search 1.2.54 (core)", "@oclif/plugin-update 4.7.59 (core)", "@oclif/plugin-version 2.2.57 (core)", "@oclif/plugin-warn-if-update-available 3.1.73 (core)", "@oclif/plugin-which 3.2.61 (core)", "@salesforce/cli 2.149.9 (core)", "agent 2.0.3 (core)", "apex 4.1.0 (core)", "api 2.0.9 (core)", "auth 5.0.6 (core)", "code-analyzer 5.0.0 (user) published 495 days ago (Tue Apr 29 2025) (latest is 5.16.0)", "data 5.1.5 (core)", "deploy-retrieve 4.1.2 (core)", "info 4.0.9 (core)", "lightning-dev 3.5.1 (user) published 375 days ago (Wed Aug 27 2025) (latest is 6.2.18)", "limits 4.0.3 (core)", "marketplace 2.0.5 (core)", "org 6.0.9 (core)", "packaging 3.0.5 (core)", "schema 4.0.5 (core)", "settings 3.0.5 (core)", "sobject 2.0.5 (core)", "telemetry 4.0.5 (core)", "templates 57.0.9 (core)", "trust 4.0.9 (core)", "ui-bundle-dev 1.2.2 (user) published 159 days ago (Tue Mar 31 2026) (latest is 1.2.4)", "user 5.0.1 (core)" ] }