Karma autoWatch Not Re-Running Tests: A Diagnostic Guide
Karma's autoWatch can silently fail to re-run tests after edits. Diagnose exclude patterns, Docker mounts, preprocessor bugs, and Node.js watcher issues with this step-by-step guide.
21 Nov 2025, 18:42 UTC

Karma starts, executes your test suite, and then goes quiet. You edit a source file, save, and wait—but no new run appears. The autoWatch flag is set to true, yet the file watcher never triggers a second execution. This guide helps you isolate the cause and restore automatic re-runs.
Recognizable condition
The failure mode is consistent: the initial run completes normally, but subsequent edits to source, test, or configuration files produce no observable reaction. There is no crash and no error dialog; Karma simply idles. Manually saving karma.conf.js itself also fails to restart the run.
autoWatch is Karma's built-in mechanism for monitoring files matched by the files array. When enabled, it relies on the operating system's file-system notification APIs (such as inotify on Linux, FSEvents on macOS, or ReadDirectoryChangesW on Windows) to schedule a new test run shortly after a change.
Cause and diagnostic table
| Clue | Likely cause | Quick diagnostic |
|---|---|---|
| Startup log never mentions watching | autoWatch disabled or overridden | Search config and CLI flags for autoWatch |
| Only some edits trigger a run | exclude pattern too broad | Compare the changed file path against exclude entries |
| New file types are ignored | Extension missing from files pattern | Check files array and preprocessor patterns |
| Docker: no events at all | Volume mount not propagating file-system events | Check container logs for mount or ENOSPC/EBUSY warnings |
| Works after removing a plugin | Custom preprocessor or plugin swallowing events | Temporarily disable custom plugins |
| Fails on macOS, works on Linux | Node.js fs.watch instability | Test with a polling interval |
Ordered checks
1. Confirm autoWatch is enabled
Run the following in your project root (no elevated permissions required):
grep -n "autoWatch" karma.conf.js
Expected check: the flag is true and is not overridden by a CLI flag such as --no-auto-watch. If the line is missing, Karma defaults to true, but an explicit false or an environment override will silence the watcher.
2. Audit exclude patterns
Open karma.conf.js and inspect the exclude array. A pattern like **/*.js inside exclude will prevent Karma from watching every JavaScript file, including your source. Compare the absolute path of a file you just edited against each exclude glob.
3. Verify watched file extensions
Karma only watches files matched by the files array (and not excluded). If you recently added .ts, .mjs, or .jsx files but files still lists only **/*.js, those files are invisible to the watcher.
4. Inspect Docker volume mounts
If Karma runs inside Docker, file-system events generated on the host may not reach the container, especially on macOS or Windows where the volume driver translates between host and guest file systems.
Run these commands on the Docker host (requires Docker CLI access):
docker ps
docker logs <container_id_or_name> 2>&1 | grep -iE "watch|ENOSPC|EBUSY"
Expected check: the container is running, and the log contains no ENOSPC (watch limit exhausted) or EBUSY (resource busy) warnings. A message such as "Cannot watch directory" indicates the mount is not propagating events.
5. Isolate preprocessors and plugins
A custom preprocessor that never calls done() or does not return a stream can stall the pipeline. Because Karma processes file changes through the same preprocessor chain, a broken plugin can silently absorb watch events.
Temporarily comment out custom entries in the preprocessors and plugins arrays, restart Karma, and edit a file. If watching resumes, audit each removed plugin.
6. Enable debug logging
Set the log level to debug to see what the watcher is doing. You can do this in karma.conf.js:
logLevel: config.LOG_DEBUG
Or pass it on the command line from the project root:
npx karma start karma.conf.js --log-level debug
Expected check: after startup, the console shows lines beginning with "Watching ..." that list the monitored paths. If those lines are absent, the watcher never initialized. If they are present but no re-run occurs, the event is not reaching the scheduler.
Fixes tied to findings
Finding: exclude pattern matches source files
Narrow the pattern so it targets generated output rather than source. For example, replace a broad exclude: ['**/*.js'] with a specific build directory:
exclude: [
'dist/**',
'coverage/**'
]
Risk: broadening files or narrowing exclude too far can cause Karma to attempt watching binary or generated files, leading to errors or high memory consumption.
Finding: missing file extensions
Add the extensions to the files array or use a broad glob:
files: [
'src/**/*.ts',
'test/**/*.spec.ts',
'src/**/*.js'
]
Finding: Docker volume not propagating events
Two practical options exist. First, adjust the volume mount flags on macOS or Windows to :cached or :delegated, which can improve event consistency. Second, switch Karma to polling by setting an interval:
autoWatch: true,
autoWatchInterval: 250
Caution: a very low autoWatchInterval increases CPU usage significantly, especially in large projects. The default is 100 ms; raising it to 250 ms or higher reduces load at the cost of latency.
Finding: preprocessor or plugin swallowing events
Ensure every custom preprocessor either returns a stream or invokes the done callback. A minimal correct pattern looks like this:
preprocessors: {
'src/**/*.js': ['myPreprocessor']
},
// In the plugin:
'myPreprocessor:preprocessor': function(content, file, done) {
// transform content...
done(content);
}
Finding: Node.js fs.watch instability
On platforms where native fs.watch is unreliable, upgrade Node.js to a current LTS release (versions before 12 had known watcher instability on some systems). If upgrading is not immediately possible, use the polling workaround shown above.
Escalation criteria
Escalate to a GitHub issue when all of the following are true:
autoWatchistrueand the debug log shows "Watching ..." messages.- The edited file matches the
filespattern and is not excluded. - No Docker mount warnings appear, or the issue reproduces outside Docker.
- Disabling all custom plugins does not restore watching.
- Polling via
autoWatchIntervalworks, but native watching does not.
Before filing, capture a full debug log, reproduce the failure in a minimal repository, and include your Node.js version, operating system, and Karma version. A poll-based configuration (autoWatch: true, autoWatchInterval: 250) is an acceptable interim workaround.
Verification and limitations
To confirm the fix, start Karma with autoWatch: true and LOG_LEVEL: debug. Wait for the "Watching ..." lines. Then edit a source file that matches the files pattern. A new test run should begin within the expected interval (default 100 ms).
If you are using Docker, run docker ps to confirm the container is healthy and inspect the Karma log for ENOSPC or EBUSY warnings.
Limitations remain: polling watchers consume more CPU than native events, and very broad file patterns can overwhelm the watcher on large repositories. Native file-system notification APIs also behave differently across operating systems, which is why a configuration that works on Linux may fail on macOS.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.