{"record":{"id":"f45fb004da436146","repo":"angular/components","slug":"proxyzonespec-is-needed-for-the-test-harnesses-but","errorCode":null,"errorMessage":"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","messagePattern":"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","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cdk/testing/testbed/task-state-zone-interceptor.ts","lineNumber":85,"sourceCode":"   * Sets up the custom task state Zone interceptor in the  `ProxyZone`. Throws if\n   * no `ProxyZone` could be found.\n   * @returns an observable that emits whenever the task state changes.\n   */\n  static setup(): Observable<TaskState> {\n    if (Zone === undefined) {\n      throw Error(\n        'Could not find ZoneJS. For test harnesses running in TestBed, ' +\n          'ZoneJS needs to be installed.',\n      );\n    }\n\n    // tslint:disable-next-line:variable-name\n    const ProxyZoneSpec = (Zone as any)['ProxyZoneSpec'] as ProxyZoneStatic | undefined;\n\n    // If there is no \"ProxyZoneSpec\" installed, we throw an error and recommend\n    // setting up the proxy zone by pulling in the testing bundle.\n    if (!ProxyZoneSpec) {\n      throw Error(\n        'ProxyZoneSpec is needed for the test harnesses but could not be found. ' +\n          'Please make sure that your environment includes zone.js/dist/zone-testing.js',\n      );\n    }\n\n    // Ensure that there is a proxy zone instance set up, and get\n    // a reference to the instance if present.\n    const zoneSpec = ProxyZoneSpec.assertPresent() as PatchedProxyZone;\n\n    // If there already is a delegate registered in the proxy zone, and it\n    // is type of the custom task state interceptor, we just use that state\n    // observable. This allows us to only intercept Zone once per test\n    // (similar to how `fakeAsync` or `async` work).\n    if (zoneSpec[stateObservableSymbol]) {\n      return zoneSpec[stateObservableSymbol]!;\n    }\n\n    // Since we intercept on environment creation and the fixture has been","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/cdk/testing/testbed/task-state-zone-interceptor.ts#L67-L103","documentation":"The Component Dev Kit (CDK) test harnesses require zone.js's ProxyZoneSpec to intercept and await async tasks during change detection. This error means Zone['ProxyZoneSpec'] is undefined at runtime because the zone-testing bundle was never loaded. The library throws early in harness setup rather than silently mis-behaving.","triggerScenarios":"Calling any TestbedHarnessEnvironment API (e.g. loader(), harnessForFixture) or creating a harness whose setup path reaches TaskStateZoneInterceptor.setup when zone.js/dist/zone-testing.js (or zone.js/plugins/zone-testing for newer versions) is not included in test files.","commonSituations":"Missing zone-testing.js entry in angular.json test file globs; switching from Karma to Jest/Vitest without loading zone testing manually; upgrading Angular/zone.js where the dist path changed (zone.js/dist/zone-testing.js -> zone.js/plugins/zone-testing.js in zone.js >= 0.11); running with zoneless/noop Zone config while harnesses still expect zone.","solutions":["Add 'node_modules/zone.js/dist/zone-testing.js' (zone.js < 0.11) or 'node_modules/zone.js/plugins/zone-testing' to the 'files'/'testFiles' list in angular.json, karma.conf.js, or your Jest/Vitest setup","Verify Zone is actually loaded before harnesses: import 'zone.js' first, then zone-testing","If using zone.js >= 0.11, update the old dist/ path which silently fails to register ProxyZoneSpec","If the app is intentionally zoneless, load zone-testing in the test setup only, or use the harness-free querying APIs"],"exampleFix":"// before (angular.json)\n\"test\": { \"options\": { \"src\": [\"test.ts\"] } }\n// karma.conf.ts files: missing zone-testing\n// after\n\"files\": [\n  \"node_modules/zone.js/dist/zone.js\",\n  \"node_modules/zone.js/dist/zone-testing.js\"\n]","handlingStrategy":"validation","validationCode":"if (!(Zone as any)?.['ProxyZoneSpec']) {\n  throw new Error('zone.js/dist/zone-testing.js is not loaded; harnesses cannot run');\n}\n// or check before creating harnesses in a shared test util:\nexpect((Zone as any)['ProxyZoneSpec']).toBeTruthy();","typeGuard":"const hasProxyZone = (): boolean =>\n  typeof Zone !== 'undefined' && !!(Zone as any)['ProxyZoneSpec'];","tryCatchPattern":"try {\n  await loader.getHarness(MyHarness);\n} catch (e) {\n  if ((e as Error).message.includes('ProxyZoneSpec is needed')) {\n    fail('Add zone.js/dist/zone-testing.js to your test setup');\n  }\n  throw e;\n}","preventionTips":["Include zone-testing in the shared test entry file so every spec has it","After upgrading zone.js, verify the bundle path (dist/ vs plugins/)","Add a smoke test that asserts ProxyZoneSpec exists before any harness use","Keep harness setup utilities in one place to centralize the zone requirement"],"tags":["testing","zonejs","configuration","angular"],"backgroundTag":"missing-zone-testing-bundle","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}