Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

[Bug]: UI mode fails with spawn EBADF on macOS when the test directory contains more than ~10k files

オープン
#43,653 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@guishiw がすでに取り組んでいます。

2026年10月28日 から。

  • #43712 @guishiw による — オープン
  • #43716 @dgozman による — オープン

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
55/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
macos, node.js, typescript
領域
devtools, testing

調査の方向性

Start with WorkerHost.startRunner in node_modules/playwright/lib/runner/index.js and trace how UI mode's FSWatcher and chokidar handle the test directory before worker processes are spawned. Reproduce on macOS using the supplied config, one test, and roughly 11,000 files; compare with a non-UI run. Done means UI mode runs and passes the test without spawn EBADF at that scale.

索引モデルが issue の本文から書いたものです。

説明

needs-triage-mac
Version

1.64.1 (also reproduced on 1.63.0)

Steps to reproduce
  1. Create a project with this playwright.config.ts:

    import { defineConfig } from '@playwright/test';
    
    export default defineConfig({
      testDir: './',
      testMatch: '**/*.spec.ts',
    });
    
  2. Add one trivial test, example.spec.ts:

    import { expect, test } from '@playwright/test';
    
    test('passes', () => {
      expect(1 + 1).toBe(2);
    });
    
  3. Put 11,000 plain files under testDir:

    mkdir src && for i in $(seq 0 10999); do echo "export const v$i = $i;" > src/file-$i.ts; done
    
  4. Run npx playwright test --ui and click Run all.

Expected behavior

The test runs and passes, as it does with npx playwright test without --ui.

Actual behavior

No test runs (0/0). The output pane shows:

Error: spawn EBADF
Error: spawn EBADF

The full stack, from a real project on 1.63.0:

Error: spawn EBADF
    at ChildProcess.spawn (node:internal/child_process:486:11)
    at spawn (node:child_process:860:9)
    at Object.fork (node:child_process:177:10)
    at WorkerHost.startRunner (node_modules/playwright/lib/runner/index.js:1915:49)
    at WorkerHost.start (node_modules/playwright/lib/runner/index.js:5473:23)
    at Dispatcher._runJobInWorker (node_modules/playwright/lib/runner/index.js:5600:20) {
  errno: -9,
  code: 'EBADF',
  syscall: 'spawn'
}

With 9,000 files instead of 11,000, the same project passes in UI mode.

Additional context

Cause. In UI mode, FSWatcher watches the project testDir (plus test dependencies) with the bundled chokidar. On macOS this keeps one open file descriptor per watched file. In our real project the UI-mode process held 10,658 open descriptors, about 10,600 of them regular files under testDir.

When a process holds more than macOS OPEN_MAX (10240) descriptors, the new stdio pipes for the worker get fd numbers above that limit. fork() with piped stdio then fails with EBADF. Raising ulimit -n doesn't help; ours is 1048576.

The same failure without Playwright:

// ebadf.cjs — node ebadf.cjs x 10200 → "ok"; node ebadf.cjs x 10300 → "EBADF"
const fs = require('fs');
const { fork } = require('child_process');

if (process.argv[2] === 'child') process.exit(0);

const n = Number(process.argv[3]);
for (let i = 0; i < n; i++) fs.openSync(__filename, 'r');
try {
  const child = fork(__filename, ['child'], { stdio: ['ignore', 'pipe', 'pipe', 'ipc'] });
  child.on('exit', () => console.log(n, 'ok'));
} catch (e) {
  console.log(n, e.code);
}

So any project with more than ~10k files under testDir cannot run tests in UI mode on macOS. Non-UI runs are not affected because they don't start the watcher.

Possible fixes.

  • Use a watcher that does not hold one descriptor per file on macOS, such as FSEvents or recursive fs.watch.
  • Watch only the test files and their dependencies, not every file under testDir.
  • Let users exclude paths from the UI-mode watcher.

Workaround. Narrow testDir so it contains fewer than ~10k files.

Environment
System:
  OS: macOS 27.0.1 (26A434), arm64
Binaries:
  Node: 26.12.1
npmPackages:
  @playwright/test: 1.64.1 (also 1.63.0)
主要言語
TypeScript
スター
98.5k
フォーク
6.7k
平均マージ
16時間 10分
マージ済み PR(30日)
305

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

microsoft/playwright のほかの issue

microsoft/playwright の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。