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
Some more info:
yarn install sometimes works, but other operations like yarn test don't.Environment
v9.7.1v1.5.14.15.6-300.fc27.x86_64Error
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:
yarn licenses generate-disclaimer > NOTICE (to generate a large NOTICE file)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?
Most helpful comment
@ebpo90 You just made my day! That's 100% correct. Renaming or removing my very large
NOTICEorNOTICE.mdfile makes the issue go away.@BYK Looks like the way to reproduce this issue consistently is to:
yarn licenses generate-disclaimer > NOTICE(to generate a largeNOTICEfile)yarnthat do any file loading, ieyarn test(if using Jest), oryarn prepublish(if that modifies your package.json)For now, I'm going to rename our
NOTICEfile toLICENSESinstead as a workaround.