{"record":{"id":"84dd7e3095253f72","repo":"microsoft/playwright","slug":"ref-param-target-not-found-in-the-current-page","errorCode":null,"errorMessage":"Ref ${param.target} not found in the current page snapshot. Try capturing new snapshot.","messagePattern":"Ref (.+?) not found in the current page snapshot\\. Try capturing new snapshot\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/tools/backend/tab.ts","lineNumber":515,"sourceCode":"  async targetLocators(params: { element?: string, target: string }[]): Promise<{ locator: playwright.Locator, resolved: string, selector: string }[]> {\n    await this._initializedPromise;\n    return Promise.all(params.map(async param => {\n      if (!param.target.match(/^(f\\d+)?e\\d+$/)) {\n        const selector = locatorOrSelectorAsSelector('javascript', param.target, this.context.config.testIdAttribute || 'data-testid');\n        const handle = await this.page.$(selector);\n        if (!handle)\n          throw new Error(`\"${param.target}\" does not match any elements.`);\n        handle.dispose().catch(() => {});\n        return { locator: this.page.locator(selector), resolved: asLocator('javascript', selector), selector };\n      } else {\n        try {\n          let locator = this.page.locator(`aria-ref=${param.target}`);\n          if (param.element)\n            locator = locator.describe(param.element);\n          const resolved = await locator.normalize();\n          return { locator, resolved: resolved.toString(), selector: locatorSelector(resolved) };\n        } catch (e) {\n          throw new Error(`Ref ${param.target} not found in the current page snapshot. Try capturing new snapshot.`);\n        }\n      }\n    }));\n  }\n\n  async waitForTimeout(time: number) {\n    if (this._javaScriptBlocked()) {\n      await new Promise(f => setTimeout(f, time));\n      return;\n    }\n\n    await this.page.evaluate(ms => new Promise(f => setTimeout(f, ms)), time).catch(() => {});\n  }\n}\n\nexport type ConsoleMessage = {\n  type: ReturnType<playwright.ConsoleMessage['type']>;\n  timestamp: number;","sourceCodeStart":497,"sourceCodeEnd":533,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/tools/backend/tab.ts#L497-L533","documentation":"Thrown by Tab.targetLocator when params.target DOES match the aria-ref pattern (/^(f\\d+)e\\d+$/), so it is resolved via page.locator('aria-ref=...').normalize(), and that resolution throws (stale or unknown ref). The catch rewrites any error into the snapshot-stale message.","triggerScenarios":"Passing an element ref (e.g. 'e7', 'f2e3') that was issued by an earlier browser_snapshot but is no longer valid — the page has changed, navigated, or the ref was from a different frame tree.","commonSituations":"Agent reusing refs across a navigation; long-running session where the snapshot expired; ref copied from a previous turn's snapshot after the DOM mutated.","solutions":["Re-invoke browser_snapshot to obtain fresh refs, then retry with the new ref.","Avoid caching refs across navigations or significant DOM mutations.","If the element is stable, switch to a robust selector instead of a snapshot ref."],"exampleFix":"// before\n// snapshot taken 5 turns ago returned ref 'e7'; DOM since changed\nawait client.callTool('browser_click', { element: 'submit', target: 'e7' }); // throws\n\n// after\nawait client.callTool('browser_snapshot', {});\n// new ref 'e9'\nawait client.callTool('browser_click', { element: 'submit', target: 'e9' });","handlingStrategy":"retry","validationCode":"function looksLikeRef(target: string): boolean {\n  return /^(f\\d+)?e\\d+$/.test(target);\n}\nfunction refAge(snapshotTurn: number, currentTurn: number): number {\n  return currentTurn - snapshotTurn;\n}","typeGuard":"function isStaleRefError(e: unknown): boolean {\n  return e instanceof Error && /Ref .* not found in the current page snapshot/.test(e.message);\n}","tryCatchPattern":"for (let attempt = 0; attempt < 2; attempt++) {\n  try {\n    await client.callTool('browser_click', { element, target: ref });\n    break;\n  } catch (e) {\n    if (isStaleRefError(e) && attempt === 0) {\n      await client.callTool('browser_snapshot', {});\n      // update `ref` from the new snapshot; continue\n    } else throw e;\n  }\n}","preventionTips":["Capture a fresh browser_snapshot before each interaction turn.","Never cache refs across navigations or page reloads.","For stable elements, prefer robust selectors (role/text/getByTestId) over refs."],"tags":["locator","element-resolution","snapshot","mcp-tool","stale-ref"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}