{"record":{"id":"2604add3243cd0a5","repo":"microsoft/playwright","slug":"element-is-outside-of-the-viewport","errorCode":null,"errorMessage":"Element is outside of the viewport","messagePattern":"Element is outside of the viewport","errorType":"exception","errorClass":"NonRecoverableDOMError","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/dom.ts","lineNumber":348,"sourceCode":"          if (result === 'error:notconnected')\n            return result;\n        }\n      } else {\n        progress.log(`attempting ${actionName} action${options.trial ? ' (trial run)' : ''}`);\n      }\n      if (!options.skipActionPreChecks && !options.force && !noAutoWaiting)\n        await this._frame._page.performActionPreChecks(progress);\n      const result = await action(progress, retry);\n      ++retry;\n      if (result === 'error:notvisible') {\n        if (options.force || noAutoWaiting)\n          throw new NonRecoverableDOMError('Element is not visible');\n        progress.log('  element is not visible');\n        continue;\n      }\n      if (result === 'error:notinviewport') {\n        if (options.force || noAutoWaiting)\n          throw new NonRecoverableDOMError('Element is outside of the viewport');\n        progress.log('  element is outside of the viewport');\n        continue;\n      }\n      if (result === 'error:optionsnotfound') {\n        if (noAutoWaiting)\n          throw new NonRecoverableDOMError('Did not find some options');\n        progress.log('  did not find some options');\n        continue;\n      }\n      if (result === 'error:optionnotenabled') {\n        if (noAutoWaiting)\n          throw new NonRecoverableDOMError('Option being selected is not enabled');\n        progress.log('  option being selected is not enabled');\n        continue;\n      }\n      if (typeof result === 'object' && 'hitTargetDescription' in result) {\n        if (noAutoWaiting)\n          throw new NonRecoverableDOMError(`${result.hitTargetDescription} intercepts pointer events`);","sourceCodeStart":330,"sourceCodeEnd":366,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/dom.ts#L330-L366","documentation":"In the same retry loop, a result of 'error:notinviewport' means the element is visible but its bounding box does not intersect the viewport. With force:true or noAutoWaiting the loop cannot retry, so it throws NonRecoverableDOMError('Element is outside of the viewport'). Without force, Playwright would scroll the element into view and retry.","triggerScenarios":"Calling a pointer action with { force: true } on an element that is rendered but scrolled out of the viewport; element in a long page below the fold where force suppresses the automatic scroll-into-view.","commonSituations":"Long pages with force-click on off-screen buttons; elements in scrollable containers where the test disabled the scroll behavior via force.","solutions":["Remove force:true so Playwright scrolls the element into view automatically.","Explicitly scroll first: await locator.scrollIntoViewIfNeeded().","Use force only when the element is already in the viewport."],"exampleFix":"// before\nawait page.locator('#footer-link').click({ force: true }); // off-screen → throws\n// after\nawait page.locator('#footer-link').scrollIntoViewIfNeeded();\nawait page.locator('#footer-link').click();","handlingStrategy":"retry","validationCode":"// Drop force so Playwright scrolls into view, or scroll explicitly.\nawait locator.scrollIntoViewIfNeeded();\nawait locator.click();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not use force on off-screen elements; let Playwright scroll-into-view.","Call scrollIntoViewIfNeeded() before forced actions on long pages.","Verify the element is in the viewport with locator.isInViewport() (where available)."],"tags":["dom","actionability","viewport","force"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}