{"record":{"id":"dcecf8dcf3e28b51","repo":"angular/components","slug":"could-not-find-zonejs-for-test-harnesses-running","errorCode":null,"errorMessage":"Could not find ZoneJS. For test harnesses running in TestBed, ZoneJS needs to be installed.","messagePattern":"Could not find ZoneJS\\. For test harnesses running in TestBed, ZoneJS needs to be installed\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/cdk/testing/testbed/task-state-zone-interceptor.ts","lineNumber":73,"sourceCode":"  private _getTaskStateFromInternalZoneState(state: HasTaskState): TaskState {\n    return {stable: !state.macroTask && !state.microTask};\n  }\n\n  static isInProxyZone(): boolean {\n    if (typeof Zone === 'undefined') {\n      return false;\n    }\n    return ((Zone as any)['ProxyZoneSpec'] as ProxyZoneStatic | undefined)?.get() !== undefined;\n  }\n\n  /**\n   * 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","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/cdk/testing/testbed/task-state-zone-interceptor.ts#L55-L91","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (test polyfills)\nimport 'zone.js/testing'; // zone.js never loaded\n// after\nimport 'zone.js';\nimport 'zone.js/testing';","handlingStrategy":"validation","validationCode":"if (typeof Zone === 'undefined') {\n  throw new Error('Add zone.js to test polyfills before using TestBed harnesses');\n}","typeGuard":"const zoneAvailable = (): boolean => typeof (globalThis as any).Zone !== 'undefined';","tryCatchPattern":"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; }","preventionTips":["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"],"tags":["angular-cdk","testing","testbed","zonejs","environment-setup"],"backgroundTag":"missing-zonejs-polyfill","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}