Yarn: Getting "spawn E2BIG" error after upgrading to yarn v1.5.1

Created on 27 Feb 2018  路  17Comments  路  Source: yarnpkg/yarn

What is the current behavior?

After upgrading from v1.3.2 to v1.5.1, all yarn commands are now failing with the following message:

error An unexpected error occurred: "spawn E2BIG".
info If you think this is a bug, please open a bug report with the information provided in "/Users/ev.haus/Git/web-platform/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

The yarn-error.log shows the following tracestack.

Trace: 
  Error: spawn E2BIG
      at _errnoException (util.js:1003:13)
      at ChildProcess.spawn (internal/child_process.js:330:11)
      at Object.exports.spawn (child_process.js:499:9)
      at /usr/local/Cellar/yarn/1.5.1/libexec/lib/cli.js:30226:24
      at new Promise (<anonymous>)
      at new F (/usr/local/Cellar/yarn/1.5.1/libexec/lib/cli.js:23451:28)
      at /usr/local/Cellar/yarn/1.5.1/libexec/lib/cli.js:30225:12
      at run (/usr/local/Cellar/yarn/1.5.1/libexec/lib/cli.js:41582:7)
      at BlockingQueue.maybePushConcurrencyQueue (/usr/local/Cellar/yarn/1.5.1/libexec/lib/cli.js:41597:7)
      at BlockingQueue.shift (/usr/local/Cellar/yarn/1.5.1/libexec/lib/cli.js:41592:10)

Rolling back to an older version of yarn makes the error go away. v1.4.0 suffers from the same issue as well. Only going back to v1.3.2 makes the issue go away.

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

Any yarn script command that writes to disk seems to be returning this, such as yarn install.

This might be a duplicate of https://github.com/yarnpkg/yarn/issues/5264

What is the expected behavior?

Should not be failing.

Environment

  • node v9.6.1
  • yarn v1.5.1
  • macOS 10.13.3
cat-bug high-priority triaged

Most helpful comment

@ebpo90 You just made my day! That's 100% correct. Renaming or removing my very large NOTICE or NOTICE.md file makes the issue go away.

@BYK Looks like the way to reproduce this issue consistently is to:

  • Checkout a project with a lot of dependencies
  • Run yarn licenses generate-disclaimer > NOTICE (to generate a large NOTICE file)
  • Run some scripts via yarn that do any file loading, ie yarn test (if using Jest), or yarn prepublish (if that modifies your package.json)

For now, I'm going to rename our NOTICE file to LICENSES instead as a workaround.

All 17 comments

Some more info:

  • I'm unable to reproduce on a Windows machine
  • I can reproduce (but not consistently) on a different MacOS box. yarn install sometimes works, but other operations like yarn test don't.
  • I can reproduce on some Linux machines as well

Environment

  • node v9.7.1
  • yarn v1.5.1
  • Linux 4.15.6-300.fc27.x86_64

Error

verbose 0.343 Error: spawn E2BIG
    at ChildProcess.spawn (internal/child_process.js:330:11)
    at Object.exports.spawn (child_process.js:500:9)
    at /usr/share/yarn/lib/cli.js:30226:24
    at new Promise (<anonymous>)
    at new F (/usr/share/yarn/lib/cli.js:23451:28)
    at /usr/share/yarn/lib/cli.js:30225:12
    at run (/usr/share/yarn/lib/cli.js:41582:7)
    at BlockingQueue.maybePushConcurrencyQueue (/usr/share/yarn/lib/cli.js:41597:7)
    at BlockingQueue.shift (/usr/share/yarn/lib/cli.js:41592:10)
    at /usr/share/yarn/lib/cli.js:41540:15
error An unexpected error occurred: "spawn E2BIG".

getconf ARG_MAX = 2097152

Hotfix

If I remove opts.env.npm_package_noticeText by setting it opts.env.npm_package_noticeText = null before const proc = child.spawn(program, args, opts); in src/util/child.js#L72 then everything works just fine.

I think this is due to the npm_package environment variables that we set for backward compatibility. When some of those fields get large, it causes the passed environment to be too big and spawn to fail. We can start removing large fields but we need a reference to measure them against or have a blacklist/whitelist.

@mkungla how large is your noticeText field in the package.json file?

@BYK I don't have noticeText field in package.json, but failing sizes are

npm_package_noticeText length 773076
size npm_package_noticeText 1.475 MiB
size opts.env 2.962 MiB

setting opts.env.npm_package_noticeText = '';

npm_package_noticeText length 0
size npm_package_noticeText 0 bytes
size opts.env 13.025 KiB

measured by adding following to https://github.com/yarnpkg/yarn/blob/master/src/util/child.js#L72

// opts.env.npm_package_noticeText = '';
//////////
let bytes = 0;
const sizeOf = obj => {
  if (obj !== null && obj !== undefined) {
    switch (typeof obj) {
      case 'number':
        bytes += 8;
        break;
      case 'string':
        bytes += obj.length * 2;
        break;
      case 'boolean':
        bytes += 4;
        break;
      case 'object':
        const objClass = Object.prototype.toString.call(obj).slice(8, -1);
        if (objClass === 'Object' || objClass === 'Array') {
          for (const key in obj) {
            if (!obj.hasOwnProperty(key)) {
              continue;
            }
            sizeOf(obj[key]);
          }
        } else {
          bytes += obj.toString().length * 2;
        }
        break;
    }
  }
  return bytes;
};

const formatSize = bytes => {
  if (bytes < 1024) return bytes + ' bytes';
  else if (bytes < 1048576) return (bytes / 1024).toFixed(3) + ' KiB';
  else if (bytes < 1073741824) return (bytes / 1048576).toFixed(3) + ' MiB';
  else return (bytes / 1073741824).toFixed(3) + ' GiB';
};
console.log('npm_package_noticeText length', opts.env.npm_package_noticeText.length);
console.log('size npm_package_noticeText', formatSize(sizeOf(opts.env.npm_package_noticeText)));
console.log('size opts.env', formatSize(sizeOf(opts.env)));
//////////

hope that helps

I also don't have noticeText set in package.json. Could this be happening due to a large dependencies or devDependencies list instead? My list is very large.

I think so aswell since yarn seems to collect that info for licenses command

yarn licenses generate-disclaimer > NOTICE.md

able to build by removing content from NOTICE.md
馃し

@ebpo90 You just made my day! That's 100% correct. Renaming or removing my very large NOTICE or NOTICE.md file makes the issue go away.

@BYK Looks like the way to reproduce this issue consistently is to:

  • Checkout a project with a lot of dependencies
  • Run yarn licenses generate-disclaimer > NOTICE (to generate a large NOTICE file)
  • Run some scripts via yarn that do any file loading, ie yarn test (if using Jest), or yarn prepublish (if that modifies your package.json)

For now, I'm going to rename our NOTICE file to LICENSES instead as a workaround.

@EvHaus thanks for digging into this! I guess we should omit these fields completely or simply have a limit for dropping large fields. What do you all think?

Can you help me understand why yarn reads/loads the NOTICE file at all? I'm not sure what you mean by "fields" in this case.

@EvHaus because that information is stored inside the "manifest information" when yarn puts the package into the cache. I'm about to submit a PR that adds it to the blacklist we already have for long fields (only covers README right now).

Is there a way we can disable the notice stuff? I have a private repo of reusable components, one of which is Notice.js, in the project root. The only way to not get the error is to delete the notice component, run yarn commands, then re-add the component again.

The components are built into the project root on purpose, so we can import them with the following style in consuming projects:

import Notice from '@company/components-repo/Notice'

Moving the dist files to a sub directory isn't a good option unless there's another way to maintain the above import style.

@BYK I am still getting this error with my decently large package.json. You can see my package.json here: https://github.com/eamodio/vscode-gitlens/blob/develop/package.json

VS Code extensions can have a pretty large contributes node -- maybe that can be ignored? activationEvents is another node that could have a bunch of data (but typically not very large).

EDIT: Can those nodes be added here: https://github.com/yarnpkg/yarn/blob/a23cc8e535afa5502e1cb9eb3269ed9fb392f7cd/src/util/execute-lifecycle-script.js#L22:14?

@eamodio yeah I'd go ahead and add it there. We can also have a priority list that we always keep and a limit on env size to start dropping other fields (with a warning on the console) if the size goes too large.

Opinions @arcanis?

@BYK I can submit a PR for those. Is there any downside to ignoring them?

Is there any downside to ignoring them?

People expecting these to exist and then getting confused :) That's why I suggested adding the console warning when we drop something not expected commonly.

I'm still getting this failure with the following GitHub Action output:
yarn install v1.19.1
info No lockfile found.
$ ./scripts/preinstall.sh
error An unexpected error occurred: "spawn E2BIG".

This is for an internal repo where I just added a large NOTICE file. Is the filename case sensitive?

Was this page helpful?
0 / 5 - 0 ratings