{"record":{"id":"d1fb6d4697015c51","repo":"microsoft/playwright","slug":"pierce-frame-mode-matched-elements-from-multiple-f","errorCode":null,"errorMessage":"Pierce-frame mode matched elements from multiple frames.","messagePattern":"Pierce-frame mode matched elements from multiple frames\\.","errorType":"exception","errorClass":"NonRecoverableDOMError","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/frameSelectors.ts","lineNumber":331,"sourceCode":"          return func({ injected, elements, info: params.info }, params.arg);\n        }, { info, scope, functionText: String(pageFunction), arg, callWithoutMatches: options.callWithoutMatches, markTargets: options.markTargets, returnByValue });\n        if (returnByValue && evalResult === '--playwright--no--result--value--')\n          return;\n        if (!returnByValue && (evalResult as JSHandle)._value === '--playwright--no--result--value--') {\n          (evalResult as JSHandle).dispose();\n          return;\n        }\n        return { result: evalResult as R | SmartHandle<R> };\n      };\n      const maybeResult = noStall ? await frame.raceAgainstEvaluationStallingEvents(getResult).catch(e => {\n        if (e instanceof EvaluationStalledError)\n          return;\n        throw e;\n      }) : await getResult();\n      if (!maybeResult)\n        continue;\n      if (aggregatedResult)\n        throw new NonRecoverableDOMError(`Pierce-frame mode matched elements from multiple frames.`);\n      aggregatedResult = { frame, info, result: maybeResult.result };\n    }\n    return aggregatedResult;\n  }\n\n  async callOnSelector<Arg, R>(\n    selector: string,\n    options: types.StrictOptions & { mainWorld?: boolean, callWithoutMatches?: boolean, scope?: ElementHandle, markTargets?: 'all' | 'first' | 'none', noDefaultPierce?: boolean },\n    pageFunction: MatchedElementsCallback<Arg, R>,\n    arg: Arg,\n  ): Promise<{ frame: Frame, info: SelectorInfo, result: R } | null> {\n    const result = await this._callOnSelectorInternal(selector, options, pageFunction, arg, true /* returnByValue */);\n    return result as { frame: Frame, info: SelectorInfo, result: R } | null;\n  }\n\n  async callOnSelectorHandle<Arg, R>(\n    selector: string,\n    options: types.StrictOptions & { mainWorld?: boolean, scope?: ElementHandle, markTargets?: 'all' | 'first' | 'none' },","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/frameSelectors.ts#L313-L349","documentation":"In pierce-frames mode the resolver may fan out across multiple iframes. If the selector matches elements in more than one frame, the result is ambiguous, so Playwright throws NonRecoverableDOMError ('Pierce-frame mode matched elements from multiple frames.') rather than silently picking one.","triggerScenarios":"Using a piercing locator (pierceFrames on or a piercing selector) where the same selector text matches elements inside two or more iframes in the subtree.","commonSituations":"Pages with multiple iframes that happen to contain the same component/selector (e.g. repeated ad slots, duplicated widgets); tests that worked until a second iframe with the same content was added.","solutions":["Make the selector more specific so it matches in only one frame.","Target the desired frame explicitly via frameLocator rather than relying on piercing.","Scope the query to a particular iframe element handle before querying inside.","Disable pierceFrames and resolve frames manually."],"exampleFix":"// before\nawait page.locator('button#go').click(); // matches 2 iframes -> throws\n// after: target one frame\nawait page.frameLocator('iframe[name=main]').locator('button#go').click();","handlingStrategy":"validation","validationCode":"// Pre-count matching frames to surface ambiguity early\nconst frames = page.frames().filter(f => await f.locator('button#go').count() > 0);\nif (frames.length > 1) throw new Error('selector matches multiple frames');","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Prefer explicit frameLocator over pierce-mode ambiguity.","Make selectors unique across the iframe subtree."],"tags":["selector","pierce-frames","frames","ambiguous"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}