Summary
flue dev can fail before starting the local development server when the parent process cannot create its config-directory watcher:
Error: Config watcher failed: EMFILE: too many open files, watch
This is especially likely in large repos, repos with many generated files, or developer machines that already have watcher pressure from editors, agents, test runners, Vite/Wrangler, or other dev servers.
Why this matters
The failure happens in the parent flue dev supervisor while watching the resolved config file directory. In the common case where flue.config.* lives at the project root, this means a single failed fs.watch(root) aborts the entire dev command before the actual Node/Cloudflare local server can run.
That blocks the normal documented development path:
flue dev does not reach the app server startup.
- Cloudflare-target apps never get to Vite/Wrangler.
- Workarounds like running generated Wrangler output directly bypass Flue's normal dev supervisor and are not equivalent to the intended development flow.
Observed reproduction
Downstream, on a Cloudflare-target Flue app:
./node_modules/.bin/flue dev --target cloudflare --port 3593
failed immediately with:
Error: Config watcher failed: EMFILE: too many open files, watch
Instrumentation of fs.watch showed the first failed watch target was the project root:
[debug-fs-watch] #1 /path/to/project
Error: Config watcher failed: EMFILE: too many open files, watch
After a fallback patch, the same normal command started successfully and served /health.
Expected behavior
If the config-directory watcher fails specifically because of watcher resource exhaustion (EMFILE or ENOSPC), flue dev should degrade gracefully instead of aborting.
Since the supervisor already has the exact resolved config file list, it can safely poll those specific files with fs.watchFile() as a fallback while preserving config restart behavior.
Non-resource watcher errors should still fail fast.
Proposed fix
PR #313 implements this:
- catches synchronous
fs.watch(directory) failures for config directories;
- catches async watcher
error events;
- falls back to polling the resolved config files for
EMFILE / ENOSPC;
- keeps the current fail-fast behavior for unrelated watcher errors;
- adds a regression test that forces
fs.watch(projectRoot) to throw EMFILE, verifies flue dev still starts, and verifies a config edit still restarts the dev session.
Related PR
Fix proposed in:
Summary
flue devcan fail before starting the local development server when the parent process cannot create its config-directory watcher:This is especially likely in large repos, repos with many generated files, or developer machines that already have watcher pressure from editors, agents, test runners, Vite/Wrangler, or other dev servers.
Why this matters
The failure happens in the parent
flue devsupervisor while watching the resolved config file directory. In the common case whereflue.config.*lives at the project root, this means a single failedfs.watch(root)aborts the entire dev command before the actual Node/Cloudflare local server can run.That blocks the normal documented development path:
flue devdoes not reach the app server startup.Observed reproduction
Downstream, on a Cloudflare-target Flue app:
failed immediately with:
Instrumentation of
fs.watchshowed the first failed watch target was the project root:After a fallback patch, the same normal command started successfully and served
/health.Expected behavior
If the config-directory watcher fails specifically because of watcher resource exhaustion (
EMFILEorENOSPC),flue devshould degrade gracefully instead of aborting.Since the supervisor already has the exact resolved config file list, it can safely poll those specific files with
fs.watchFile()as a fallback while preserving config restart behavior.Non-resource watcher errors should still fail fast.
Proposed fix
PR #313 implements this:
fs.watch(directory)failures for config directories;errorevents;EMFILE/ENOSPC;fs.watch(projectRoot)to throwEMFILE, verifiesflue devstill starts, and verifies a config edit still restarts the dev session.Related PR
Fix proposed in: