Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

child_process.spawn produces empty string for various commands (node, npm, ncu) #13

Closed
kleinfreund opened this issue Aug 11, 2021 · 6 comments

Comments

@kleinfreund
Copy link

(initially reported in nodesource/distributions#843)


  • Version: v12.1.0, v13.1.0, v13.12.0, v14.10.1, v15.6.0, v16.6.1
  • Platform: Linux RAUMSTATION 5.0.0-13-generic 14-Ubuntu SMP Mon Apr 15 14:59:14 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
  • Subsystem: child process (?)

I switched from the PPA binary (https://github.com/nodesource/distributions/blob/master/README.md#debinstall) to the snap binary (https://snapcraft.io/node). This started to break the ncu -g command. Originally, I opened an issue with npm-check-updates, but it doesn’t seem to be an issue on their end (for reference: raineorshine/npm-check-updates#536).

Only with the snap binary do I get the following error:

/home/phil/.npm-global/lib/node_modules/npm-check-updates/lib/npm-check-updates.js:387
        throw err;
        ^

Error: Expected JSON from "npm ls". This could be due to npm instability.


    at parseJson (/home/phil/.npm-global/lib/node_modules/npm-check-updates/lib/package-managers/npm.js:38:15)
    at /home/phil/.npm-global/lib/node_modules/npm-check-updates/lib/package-managers/npm.js:144:30
    at processTicksAndRejections (internal/process/task_queues.js:89:5)

The command that is executed with child_process.spawn is npm ls --global --depth=0 --json which produces the correct JSON with both the PPA and the snap binary when executed directly from the terminal.

Steps to reproduce:

Create a reproduction.js file containing the following code and run node reproduction.js with node being a Node.js binary from a Snap source (reproduces with all versions from v12 to v14 at least).

const { spawnSync } = require('child_process')

// Both these spawn commands will yield nothing in their stdout.
// The latter should just contain a Node version tring such as `v14.10.1`.

// npm ls --global --depth=0 --json
const npmListOutput = String(spawnSync('npm', ['ls', '--global', '--depth=0', '--json']).stdout)
console.log({ npmListOutput });

// node --version
const nodeVersionOutput = String(spawnSync('node', ['--version']).stdout)
console.log({ nodeVersionOutput });

To switch around the Node binary on Ubuntu:

  1. Uninstall Node.

    sudo apt remove nodejs
    
  2. Install Node via Snap.

    sudo snap install node --channel=16/stable --classic
    
  3. Verify that Snap’s Node is used (i.e. on my system, the binary is reported to be in /snap/bin/node when running which node).

  4. Run npm-check-updates with the global flag.

    ncu -g
    
  5. Remove Node via Snap.

    sudo snap remove node
    
  6. Install Node via apt.

    sudo apt install nodejs
    
@rvagg
Copy link
Member

rvagg commented Aug 19, 2021

Yeah .. so .. snaps and spawn aren't awesome due to the funky way they they do paths, I've struggled to figure out the best way to deal with this.

One option to try might be to ln -s /snap/bin/node /usr/bin/node which I've seen some snaps recommend, which is a little nasty but might help solve some path problems.

I've also been forced to use /snap/node/current/bin/node as my path before to get around these problems. Again, a little nasty but can work.

Let me know if either of those options work for you. Unfortunately there are enough limitations that it's not unreasonable to suggest moving back to a native package whenever you need to do anything that moves outside of a happy path of usage (native addons add another layer of problems to the mix).

@etatanova
Copy link

Hi! We installed Node.js via snap store and tried to use exec and spawn functions in the VS Code extension environment. In the test extension we could also reproduce the same incorrect behavior as described in this issue. The functions for spawning child processes skip the execution of npm and CLI commands (based on Node.js scripts) and return just an empty result or an error.

@rvagg
Copy link
Member

rvagg commented Sep 28, 2021

Hey folks, so I recently ran into a similar issue with the combination of VSCode and Golang installed from Snaps, it felt a lot like this one and I'm pretty sure it's all Apparmor-related because of the funky process isolation Snaps are trying to do. Anyway, the workaround here has been working great for that particular issue: https://www.mail-archive.com/ubuntu-bugs@lists.ubuntu.com/msg5924452.html

I haven't tried this to work around Node.js issues (mostly I'm not using it via Snap these days because of these problems!) but someone in this thread could give it a try and report back.

@m-thomson
Copy link

m-thomson commented Nov 5, 2021

I'm using Node-Red to launch a NodeJS instance and getting no output at all. I noticed this entry in syslog which occurred when running the Node-Red "flow":

Nov 5 18:45:59 ss1 kernel: [77021.759179] audit: type=1400 audit(1636137959.907:184): apparmor="DENIED" operation="file_inherit" profile="/snap/snapd/13640/usr/lib/snapd/snap-confine" pid=24351 comm="snap-confine" family="unix" sock_type="stream" protocol=0 requested_mask="send receive" denied_mask="send receive" addr=none peer_addr=none

Possibly related?

@kleinfreund
Copy link
Author

I’m closing this as there doesn’t seem to be any interest in reproducing or fixing this.

@giner
Copy link

giner commented Mar 4, 2023

This is still an issue and requires a fix. More details is on the the following issue nodejs/node#37982 and https://bugs.launchpad.net/ubuntu/+source/snapd/+bug/1849753. A workaround is here nodejs/node#37982 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants