Skip to content

npm installer: wrapper exits 0 when the binary is killed by a signal #2523

Description

@katspaugh

The npm installer's wrapper exits 0 when the binary it runs is killed by a signal.

Package.run in cargo-dist/templates/installer/npm/binary-install.js ends with:

const result = spawnSync(binPath, args, options);
if (result.error) {
  error(result.error);
}
process.exit(result.status);

When the child is terminated by a signal (for example the OOM killer, or SIGKILL), spawnSync returns status: null and signal: 'SIGKILL'. process.exit(null) exits with code 0, so the npm wrapper reports success for a binary that never finished.

Minimal reproduction (Node 20.20.2, same logic as the template):

const { spawnSync } = require('child_process');
const result = spawnSync('sh', ['-c', 'kill -9 $$'], { stdio: 'inherit' });
console.error(`status=${result.status} signal=${result.signal}`); // status=null signal=SIGKILL
process.exit(result.status); // wrapper exits 0

We hit this with @posthog/cli, which ships this installer (checked 0.16.2 and 0.18.9). A build step runs the CLI to upload source maps and treats exit code 0 as "uploaded". A killed upload therefore looks successful to CI.

Suggested fix: treat a signal as failure, e.g.

if (result.signal) {
  error(`${binaryName} was terminated by ${result.signal}`);
}
process.exit(result.status);

(error() already exits 1.) Alternatively use process.exit(result.status ?? 1), or re-raise the same signal on the wrapper with process.kill(process.pid, result.signal) so callers see the original signal.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions