angular/components · critical
Could not find ZoneJS. For test harnesses running in TestBed
Error message
Could not find ZoneJS. For test harnesses running in TestBed, ZoneJS needs to be installed.
What it means
Thrown by TaskStateZoneInterceptor.setup when the global Zone is undefined. TestBed-based harnesses rely on ZoneJS (specifically ProxyZone) to track async tasks and know when the app is stable; without ZoneJS installed the harness cannot monitor task state, so setup aborts.
Source
Thrown at src/cdk/testing/testbed/task-state-zone-interceptor.ts:73
private _getTaskStateFromInternalZoneState(state: HasTaskState): TaskState {
return {stable: !state.macroTask && !state.microTask};
}
static isInProxyZone(): boolean {
if (typeof Zone === 'undefined') {
return false;
}
return ((Zone as any)['ProxyZoneSpec'] as ProxyZoneStatic | undefined)?.get() !== undefined;
}
/**
* Sets up the custom task state Zone interceptor in the `ProxyZone`. Throws if
* no `ProxyZone` could be found.
* @returns an observable that emits whenever the task state changes.
*/
static setup(): Observable<TaskState> {
if (Zone === undefined) {
throw Error(
'Could not find ZoneJS. For test harnesses running in TestBed, ' +
'ZoneJS needs to be installed.',
);
}
// tslint:disable-next-line:variable-name
const ProxyZoneSpec = (Zone as any)['ProxyZoneSpec'] as ProxyZoneStatic | undefined;
// If there is no "ProxyZoneSpec" installed, we throw an error and recommend
// setting up the proxy zone by pulling in the testing bundle.
if (!ProxyZoneSpec) {
throw Error(
'ProxyZoneSpec is needed for the test harnesses but could not be found. ' +
'Please make sure that your environment includes zone.js/dist/zone-testing.js',
);
}
// Ensure that there is a proxy zone instance set up, and getView on GitHub (pinned to 0411926e7d)
Solutions
- Add zone.js to test polyfills (polyfills.ts or angular.json test architect polyfills list) — 'zone.js' in polyfills array or `import 'zone.js'` in test setup.
- Keep TestBed tests in NgZone/ProxyZone; only go zoneless for tests that do not use harnesses.
- If truly zoneless, use a different testing approach (e.g. raw TestElement queries) instead of component harnesses that rely on task-state interception.
Example fix
// before (test polyfills) import 'zone.js/testing'; // zone.js never loaded // after import 'zone.js'; import 'zone.js/testing';
Defensive patterns
Strategy: validation
Validate before calling
if (typeof Zone === 'undefined') {
throw new Error('Add zone.js to test polyfills before using TestBed harnesses');
} Type guard
const zoneAvailable = (): boolean => typeof (globalThis as any).Zone !== 'undefined';
Try / catch
try { return await harness.loader().getAllHarnesses(MyHarness); } catch (e) { if ((e as Error).message.includes('Could not find ZoneJS')) throw new Error('zone.js missing from test setup', {cause: e}); throw e; } Prevention
- Include 'zone.js' in angular.json test polyfills (or import 'zone.js' in test-setup.ts)
- Re-check polyfills after Angular upgrades and zoneless migrations
- If going zoneless, plan a non-harness testing strategy for those specs
When it happens
Trigger: Running TestBed-based component harness tests in a zoneless setup: zone.js missing from test.ts/polyfills.ts, Angular configured with provideExperimentalZonelessChangeDetection(), or the zone.js import removed from test polyfills.
Common situations: Migrating an app to zoneless Angular while keeping harness-based tests; new test bundler configs (Vite/Jest) that don't include zone.js in the setup files; upgrading Angular where zone.js polyfill registration changed.
Related errors
- No keys have been specified.
- Index must not be negative
- No harness was located at index ${offset}
- CDK Component harness query must contain at least one elemen
- Failed to find element matching one of the following queries
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/dcecf8dcf3e28b51.
Report an issue: GitHub.