angular/angular · error · Error
Missing ProxyZoneSpec
Error message
Missing ProxyZoneSpec
What it means
Thrown by zone.js's jest patch (jest.ts:35): patching jest requires ProxyZoneSpec (from the proxy zone-spec patch) so each test can retroactively install zones (fakeAsync etc.). If Zone['ProxyZoneSpec'] is undefined when the jest patch runs, it aborts with this error. Unlike the jasmine patch there is no SyncTestZoneSpec existence check here, but jest still relies on both specs being registered.
Source
Thrown at packages/zone.js/lib/jest/jest.ts:35
return;
}
// From jest 29 and jest-preset-angular v13, the module transform logic
// changed, and now jest-preset-angular use the use the tsconfig target
// other than the hardcoded one, https://github.com/thymikee/jest-preset-angular/issues/2010
// But jest-angular-preset doesn't introduce the @babel/plugin-transform-async-to-generator
// which is needed by angular since `async/await` still need to be transformed
// to promise for ES2017+ target.
// So for now, we disable to output the uncaught error console log for a temp solution,
// until jest-preset-angular find a proper solution.
(Zone as any)[api.symbol('ignoreConsoleErrorUncaughtError')] = true;
jest['__zone_patch__'] = true;
const ProxyZoneSpec = (Zone as any)['ProxyZoneSpec'];
const SyncTestZoneSpec = (Zone as any)['SyncTestZoneSpec'];
if (!ProxyZoneSpec) {
throw new Error('Missing ProxyZoneSpec');
}
const rootZone = Zone.current;
const syncZone = rootZone.fork(new SyncTestZoneSpec('jest.describe'));
const proxyZoneSpec = new ProxyZoneSpec();
const proxyZone = rootZone.fork(proxyZoneSpec);
function wrapDescribeFactoryInZone(originalJestFn: Function) {
return function (this: unknown, ...tableArgs: any[]) {
const originalDescribeFn = originalJestFn.apply(this, tableArgs);
return function (this: unknown, ...args: any[]) {
args[1] = wrapDescribeInZone(args[1]);
return originalDescribeFn.apply(this, args);
};
};
}
function wrapTestFactoryInZone(originalJestFn: Function) {View on GitHub (pinned to 51cb07e980)
Solutions
- In jest config, load zone.js then zone.js/testing in setupFiles: ['zone.js', 'zone.js/testing'] (or use jest-preset-angular's preset which does this).
- Verify the bundler keeps zone.js side effects (sideEffects: true for zone.js packages).
- If assembling files manually, include zone.js/lib/zone-spec/proxy before zone.js/lib/jest/jest.
Example fix
// before (jest.config.js) setupFiles: ['./src/setup-jest.ts'] // setup-jest.ts only imports 'zone.js/lib/jest/jest' // after (setup-jest.ts) import 'zone.js'; import 'zone.js/testing';
Defensive patterns
Strategy: validation
Validate before calling
// jest setup: verify proxy spec registered before tests run
import 'zone.js';
import 'zone.js/testing';
if (!(globalThis as any).Zone?.ProxyZoneSpec) {
throw new Error('zone.js/testing failed to register ProxyZoneSpec — check import order/sideEffects.');
} Type guard
function hasProxyZoneSpecForJest(): boolean { return !!(globalThis as any).Zone?.ProxyZoneSpec; } Prevention
- Use jest-preset-angular's preset, which loads zone.js/testing in the correct order.
- Ensure bundler config keeps zone.js module side effects enabled.
When it happens
Trigger: Loading zone.js/jest (or zone.js/testing under jest) without the proxy zone-spec having registered ProxyZoneSpec — wrong import order, partial bundles, or a bundler that drops the side-effectful proxy patch.
Common situations: Jest + Angular setups with a custom setupFiles list that omits 'zone.js/testing'; version upgrades of zone.js or jest-preset-angular changing required imports; ESM configurations dropping side effects.
Related errors
- Missing: zone.js
- Missing: SyncTestZoneSpec
- Missing: ProxyZoneSpec
- Unexpected Zone: ${Zone.current.name}
- Missing ProxyZoneSpec
AI-assisted analysis of angular/angular@51cb07e980 (2026-08-22).
Data as JSON: /api/errors/282437e66cbc656f.
Report an issue: GitHub.