{"record":{"id":"d3267f2547da0f02","repo":"microsoft/playwright","slug":"options-waitfor-is-not-supported-did-you-mean-opt-d3267f","errorCode":null,"errorMessage":"options.waitFor is not supported, did you mean options.state?","messagePattern":"options\\.waitFor is not supported, did you mean options\\.state\\?","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/frames.ts","lineNumber":842,"sourceCode":"    return await progress.race(this._evaluateExpressionHandle(expression, options, arg));\n  }\n\n  private async _evaluateExpressionHandle(expression: string, options: { isFunction?: boolean, world?: types.World } = {}, arg?: any): Promise<js.JSHandle<any>> {\n    const context = await this.context(options.world ?? 'main');\n    const value = await context.evaluateExpressionHandle(expression, options, arg);\n    return value;\n  }\n\n  async querySelector(progress: Progress, selector: string, options: types.StrictOptions): Promise<dom.ElementHandle<Element> | null> {\n    this.apiLog(`    finding element using the selector \"${selector}\"`);\n    return progress.race(this.selectors.query(selector, options));\n  }\n\n  async waitForSelector(progress: Progress, selector: string, performActionPreChecksAndLog: boolean, options: types.WaitForElementOptions, scope?: dom.ElementHandle): Promise<dom.ElementHandle<Element> | null> {\n    if ((options as any).visibility)\n      throw new Error('options.visibility is not supported, did you mean options.state?');\n    if ((options as any).waitFor && (options as any).waitFor !== 'visible')\n      throw new Error('options.waitFor is not supported, did you mean options.state?');\n    const { state = 'visible' } = options;\n    if (!['attached', 'detached', 'visible', 'hidden'].includes(state))\n      throw new Error(`state: expected one of (attached|detached|visible|hidden)`);\n    if (performActionPreChecksAndLog)\n      progress.log(`waiting for ${this._asLocator(selector)}${state === 'attached' ? '' : ' to be ' + state}`);\n    const promise = this.retryWithProgressAndBackoff(progress, async (progress, continuePolling) => {\n      if (performActionPreChecksAndLog)\n        await this._page.performActionPreChecks(progress);\n\n      if (scope && await progress.race(scope.evaluateInUtility(([injected, node]) => node.isConnected, {})) !== true)\n        throw new dom.NonRecoverableDOMError('Element is not attached to the DOM');\n\n      const resolved = await progress.race(this.selectors.callOnSelectorHandle(selector, { ...options, scope }, ({ injected, elements }) => {\n        const element: Element | undefined  = elements[0];\n        const visible = element ? injected.utils.isElementVisible(element) : false;\n        let log = '';\n        if (elements.length > 1)\n          log = `  locator resolved to ${elements.length} elements. Proceeding with the first one: ${injected.previewNode(elements[0])}`;","sourceCodeStart":824,"sourceCodeEnd":860,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/frames.ts#L824-L860","documentation":"waitForSelector rejects the legacy options.waitFor property (except the value 'visible', which maps onto the default). Any other waitFor value triggers the error with the hint to use options.state instead.","triggerScenarios":"Calling waitForSelector with options.waitFor set to a non-'visible' value (e.g. 'load', 'domcontentloaded', 'networkidle') - usually confused with page.waitForLoadState's waitUntil semantics.","commonSituations":"Mixing up waitForSelector's element-state option with waitForLoadState's lifecycle option; copy-pasting options across the two APIs; legacy code from an API change.","solutions":["Remove options.waitFor and set options.state to 'visible'|'hidden'|'attached'|'detached' as needed.","If you actually wanted lifecycle, call page.waitForLoadState(...) separately."],"exampleFix":"// before\nawait page.waitForSelector('#x', { waitFor: 'load' }); // throws\n// after\nawait page.waitForSelector('#x', { state: 'visible' });\nawait page.waitForLoadState('load');","handlingStrategy":"validation","validationCode":"// Strip/redirect the legacy key\nif ('waitFor' in opts && opts.waitFor !== 'visible') {\n  // caller probably meant load-state; split the call\n  await page.waitForLoadState(opts.waitFor);\n  delete opts.waitFor;\n}","typeGuard":"function hasLegacyWaitFor(o: any): boolean { return 'waitFor' in o && o.waitFor !== 'visible'; }","tryCatchPattern":"null","preventionTips":["Keep element-state waits (waitForSelector) and lifecycle waits (waitForLoadState) separate.","Do not pass lifecycle values into waitForSelector options."],"tags":["selector","api-migration","validation"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}