{"id":"46eeb94265b2c432","repo":"jestjs/jest","slug":"jsdom-did-not-return-a-window-object","errorCode":null,"errorMessage":"JSDOM did not return a Window object","messagePattern":"JSDOM did not return a Window object","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/jest-environment-jsdom-abstract/src/index.ts","lineNumber":98,"sourceCode":"        : '<!DOCTYPE html>',\n      {\n        pretendToBeVisual: true,\n        resources:\n          typeof projectConfig.testEnvironmentOptions.userAgent === 'string'\n            ? new ResourceLoader({\n                userAgent: projectConfig.testEnvironmentOptions.userAgent,\n              })\n            : undefined,\n        runScripts: 'dangerously',\n        url: 'http://localhost/',\n        virtualConsole,\n        ...projectConfig.testEnvironmentOptions,\n      },\n    );\n    const global = (this.global = this.dom.window as unknown as Win);\n\n    if (global == null) {\n      throw new Error('JSDOM did not return a Window object');\n    }\n\n    // TODO: remove at some point - for \"universal\" code (code should use `globalThis`)\n    global.global = global;\n\n    // Node's error-message stack size is limited at 10, but it's pretty useful\n    // to see more than that when a test fails.\n    this.global.Error.stackTraceLimit = 100;\n    installCommonGlobals(global, projectConfig.globals);\n\n    // TODO: remove this ASAP, but it currently causes tests to run really slow\n    global.Buffer = Buffer;\n\n    // Report uncaught errors.\n    this.errorEventListener = event => {\n      if (userErrorListenerCount === 0 && event.error != null) {\n        process.emit('uncaughtException', event.error);\n      }","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/jestjs/jest/blob/f49721c78e195558b40913977c9230f5b7f559d8/packages/jest-environment-jsdom-abstract/src/index.ts#L80-L116","documentation":"After constructing a JSDOM instance the environment assigns `this.global = this.dom.window`. If `dom.window` is null/undefined (jsdom failed to build a Window), the environment cannot install globals and throws at index.ts:98. This guards every subsequent global assignment from a null dereference.","triggerScenarios":"JSDOM internally fails to produce a window — e.g. an unrecoverable parse error on the provided `testEnvironmentOptions.html`, a jsdom build that is corrupted, or a VirtualConsole/ResourceLoader misconfiguration that short-circuits window creation.","commonSituations":"Passing invalid `testEnvironmentOptions.html` (non-string handled, but a bad ResourceLoader/userAgent object can throw inside jsdom); an incompatible jsdom version that changed constructor semantics; a native module load failure in jsdom on a restricted CI image.","solutions":["Simplify testEnvironmentOptions to defaults and re-add options one at a time to find the trigger.","Upgrade/downgrade jsdom to a known-good version matching the adapter.","Run a minimal JSDOM script in isolation to confirm jsdom itself produces a window.","Check for native dependency issues (canvas) and install the prebuilt binaries if needed."],"exampleFix":"// before (jest.config)\ntestEnvironmentOptions: {\n  html: complexBrokenHtmlString,\n  resources: new (require('jsdom').ResourceLoader)({ strictSSL: 'maybe' }),\n}\n\n// after\ntestEnvironmentOptions: {\n  html: '<!DOCTYPE html>',\n}","handlingStrategy":"try-catch","validationCode":"// sanity-check jsdom in isolation before running the suite\nconst {JSDOM} = require('jsdom');\nconst dom = new JSDOM('<!DOCTYPE html>');\nif (dom.window == null) throw new Error('jsdom produced no window');","typeGuard":"const hasWindow = (dom: { window: unknown | null }): dom is { window: Window } => dom.window != null;","tryCatchPattern":"try {\n  testEnvironmentOptions = { html };\n} catch (e) {\n  // fall back to defaults if a custom html/resource breaks window creation\n  testEnvironmentOptions = {};\n}","preventionTips":["Start from default testEnvironmentOptions and add fields incrementally.","Pin a known-good jsdom version.","Isolate jsdom in a scratch script when debugging."],"tags":["jest-environment","jsdom","config","startup"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}