Yarn: 0.26.1 breaks `yarn outdated` command

Created on 4 Jul 2017  路  19Comments  路  Source: yarnpkg/yarn

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

After upgrading from 0.24.6 to 0.27.5 via Homebrew, I can no longer use the yarn outdated command due to this error:

Command failed: yarn outdated

Error: ENOENT: no such file or directory, open 'child_process.js'
    at Object.fs.openSync (fs.js:651:18)
    at Object.fs.readFileSync (fs.js:553:33)
    at CallsiteRecord.renderSync (/Users/evgueni.naverniouk/Git/web-platform/node_modules/callsite-record/lib/index.js:214:26)
    at checkVersions.run.catch (/Users/evgueni.naverniouk/Git/web-platform/node_modules/check-npm-versions/bin/cli.js:41:41)
    at tryCatcher (/Users/evgueni.naverniouk/Git/web-platform/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/Users/evgueni.naverniouk/Git/web-platform/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/Users/evgueni.naverniouk/Git/web-platform/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/Users/evgueni.naverniouk/Git/web-platform/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/Users/evgueni.naverniouk/Git/web-platform/node_modules/bluebird/js/release/promise.js:689:18)
    at Async._drainQueue (/Users/evgueni.naverniouk/Git/web-platform/node_modules/bluebird/js/release/async.js:133:16)
    at Async._drainQueues (/Users/evgueni.naverniouk/Git/web-platform/node_modules/bluebird/js/release/async.js:143:10)
    at Immediate.Async.drainQueues (/Users/evgueni.naverniouk/Git/web-platform/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:800:20)
    at tryOnImmediate (timers.js:762:5)
    at processImmediate [as _immediateCallback] (timers.js:733:5)

Downgrading back down to 0.24.6 makes the error go away.

If the current behavior is a bug, please provide the steps to reproduce.

brew upgrade && brew upgrade
yarn outdated

What is the expected behavior?

No crash.

Please mention your node.js, yarn and operating system version.

Node v8.1.3
MacOS 10.12.5

cat-bug triaged

Most helpful comment

Seems there are indeed some special conditions that need to be setup to be able to reproduce this. The 2 things of note are:

  • You need to run yarn outdated via a Node script via child_process.exec(). Running via command line regularly works fine.
  • You need to have a Github URL package in your package.json (eg. "ginman86/jsonlint"). Regular versioned packages work fine.

I have created a reproducible test repo here: https://github.com/EvNaverniouk/yarn3822

Steps to reproduce

  • git clone https://github.com/EvNaverniouk/yarn3822.git
  • Install packages via yarn install
  • Ensure you're on Yarn 0.27.5 (run yarn --version to check)
  • Run node test.js
  • BUG: Script fails to run with:
    at ChildProcess.exithandler (child_process.js:270:12)
    at emitTwo (events.js:125:13)
    at ChildProcess.emit (events.js:213:7)
    at maybeClose (internal/child_process.js:897:16)
    at Socket.stream.socket.on (internal/child_process.js:340:11)
    at emitOne (events.js:115:13)
    at Socket.emit (events.js:210:7)
    at Pipe._handle.close [as _onclose] (net.js:549:12) killed: false, code: 1, signal: null, cmd: 'yarn outdated' }

Notes

  1. If you run yarn outdated via the command line -- it works fine.
  2. If you reset your local yarn version via brew switch yarn 0.24.6. Then run node test.js again -- it works fine.
  3. If you go into package.json and remove the jsonlint dependency and replace it with something else that is a versioned package (eg. "react": "latest"), then run node test.js again -- it works fine.

Any idea what could be going wrong?

All 19 comments

Are you sure that error is coming from Yarn itself? The call stack contains Bluebird, which is a library that we don't use in Yarn.

Yeah, it's very strange indeed. It's almost like Yarn is calling into my node_modules directory for some reason. The reasons I suspect Yarn because:

  • It only happens after upgrading to 0.27.5, downgrading makes the issue go away
  • It doesn't happen when using npm

@EvNaverniouk would you mind providing more specific and isolated reproduction steps since right now this seems a bit hard to replicate and verify. That would also help you narrow down the issue to yarn (or not).

Seems there are indeed some special conditions that need to be setup to be able to reproduce this. The 2 things of note are:

  • You need to run yarn outdated via a Node script via child_process.exec(). Running via command line regularly works fine.
  • You need to have a Github URL package in your package.json (eg. "ginman86/jsonlint"). Regular versioned packages work fine.

I have created a reproducible test repo here: https://github.com/EvNaverniouk/yarn3822

Steps to reproduce

  • git clone https://github.com/EvNaverniouk/yarn3822.git
  • Install packages via yarn install
  • Ensure you're on Yarn 0.27.5 (run yarn --version to check)
  • Run node test.js
  • BUG: Script fails to run with:
    at ChildProcess.exithandler (child_process.js:270:12)
    at emitTwo (events.js:125:13)
    at ChildProcess.emit (events.js:213:7)
    at maybeClose (internal/child_process.js:897:16)
    at Socket.stream.socket.on (internal/child_process.js:340:11)
    at emitOne (events.js:115:13)
    at Socket.emit (events.js:210:7)
    at Pipe._handle.close [as _onclose] (net.js:549:12) killed: false, code: 1, signal: null, cmd: 'yarn outdated' }

Notes

  1. If you run yarn outdated via the command line -- it works fine.
  2. If you reset your local yarn version via brew switch yarn 0.24.6. Then run node test.js again -- it works fine.
  3. If you go into package.json and remove the jsonlint dependency and replace it with something else that is a versioned package (eg. "react": "latest"), then run node test.js again -- it works fine.

Any idea what could be going wrong?

@EvNaverniouk amazing work about reproduction steps, thank you! I'll look into this as soon as possible.

I don't know what may be wrong but I'd just use git bisect to pinpoint the diff that caused the issue.

@EvNaverniouk Would you be able to try 0.25.x and 0.26.x and see if the issue occurs with those too? It'd be great to narrow it down to a particular version. You can find all versions in the release section: https://github.com/yarnpkg/yarn/releases

@Daniel15 Looks like those versions aren't available on Homebrew. Where are the install instructions for MacOS? Not quite sure how to install directly from the release packages.

@EvNaverniouk you can clone the git repo and run them directly if you want to do that. Off the top of my head, so sorry if one of these is wrong, but the steps are roughly:

  • git clone {yarn url}
  • cd yarn
  • git fetch --tags
  • git checkout tags/v0.24.6 {or whatever version}
  • yarn build
  • cd /projects/your-project
  • node /projects/yarn/bin/yarn.js outdated

although if you are running yarn from a script, you'll probably have to change that script too.

I can confirm the above steps as I'm using the same to test local tweaks to yarn as a development branch.

Where are the install instructions for MacOS?

Download the tar.gz, extract it (tar zvxf yarn-0.xx.xx.tar.gz), then run bin/yarn. You can also build from source (like @rally25rs mentioned above) but this takes more effort.

Finally got around to doing some version testing.

  • v0.24.6 works fine
  • v0.25.4 works fine
  • v0.26.1 broken
  • v0.27.0 broken
  • v0.27.5 broken

So it looks like the issue was introduced between 0.25.4 and v0.26.1

After testing:
The command works as expected. yarn outdated exits with code 1 when there are outdated dependencies, and git (exotic) dependencies always count as outdated.
Please check #3483 for details.

@Volune I'm not seeing a regular exit code 1 however. I'm seeing a failure with this error message:

Error: ENOENT: no such file or directory, open 'child_process.js'

@EvHaus I think that one of the libraries you use is not aware that yarn outdated may now return 1, and wrongly interpret an exception resulting from this incompatibility. The exception you provided is not from Yarn.

@Volune I was able to reproduce the issue without any third-party modules at all. See: https://github.com/EvHaus/yarn3822 for a tiny reproducible test case.

yarn outdated exit code 1 is not reasonable.

@EvHaus this is what I get from your test project:

$ yarn --version
0.27.5

$ node --version
v8.0.0

$ git clone [email protected]:EvHaus/yarn3822.git
Cloning into 'yarn3822'...
remote: Counting objects: 6, done.
remote: Total 6 (delta 0), reused 0 (delta 0), pack-reused 6
Receiving objects: 100% (6/6), done.

$ cd yarn3822/

$ yarn
yarn install v0.27.5
warning package.json: License should be a valid SPDX license expression
warning yarn3822: License should be a valid SPDX license expression
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
Done in 2.48s.

$ yarn outdated
yarn outdated v0.27.5
warning package.json: License should be a valid SPDX license expression
warning yarn3822: License should be a valid SPDX license expression
Package  Current Wanted Latest Package Type URL
jsonlint 1.7.0   exotic exotic dependencies ginman86/jsonlint
Done in 0.07s.

$ node test.js
{ Error: Command failed: yarn outdated
warning package.json: License should be a valid SPDX license expression
warning yarn3822: License should be a valid SPDX license expression

    at ChildProcess.exithandler (child_process.js:252:12)
    at emitTwo (events.js:125:13)
    at ChildProcess.emit (events.js:213:7)
    at maybeClose (internal/child_process.js:887:16)
    at Socket.stream.socket.on (internal/child_process.js:340:11)
    at emitOne (events.js:115:13)
    at Socket.emit (events.js:210:7)
    at Pipe._handle.close [as _onclose] (net.js:546:12) killed: false, code: 1, signal: null, cmd: 'yarn outdated' }

The error output on the last command is printed by the error handler in your test.js code, which is correct due to the 1 exit code (code: 1 in the output error object).

I don't get anything with ENOENT 'child_process.js' in it.

Ok, so I suppose this is expected behavior then. Thanks for digging into it.

Was this page helpful?
0 / 5 - 0 ratings