macOS runner: "Too many open files" (ulimit) in CI
A process hit the per-process open file descriptor limit. macOS ships a relatively low default ulimit -n, so bundlers, test runners, and watchers that open many files at once fail with EMFILE.
What this error means
A build fails with "Error: EMFILE: too many open files" or "Too many open files" or "Too many open files - getcwd", often from a JS bundler, watcher, or a large parallel build.
Error: EMFILE: too many open files, open '/Users/runner/work/app/node_modules/...'
at Object.openSync (node:fs:...)Common causes
The default descriptor limit is too low
macOS sets a modest soft ulimit -n. Tools that open thousands of files concurrently exceed it and get EMFILE.
A file watcher tracks too many paths
Watch-mode tools open a descriptor per watched file; large trees blow past the limit.
How to fix it
Raise the open file limit for the job
- Check the current limit with
ulimit -n. - Raise the soft limit at the start of the step (up to the hard limit).
- Run the build in the same shell so the new limit applies.
ulimit -n 65536
ulimit -n
npm run buildReduce concurrent open files
Lower parallelism or disable file watching in CI so fewer descriptors are open at once.
CI=true npm test -- --maxWorkers=2How to prevent it
- Raise
ulimit -nearly for file-heavy macOS jobs. - Disable watch mode in CI.
- Cap parallelism so descriptor use stays under the limit.