microsoft/playwright · error · Error
Ref ${param.target} not found in the current page snapshot.
Error message
Ref ${param.target} not found in the current page snapshot. Try capturing new snapshot. What it means
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.
Source
Thrown at packages/playwright-core/src/tools/backend/tab.ts:515
async targetLocators(params: { element?: string, target: string }[]): Promise<{ locator: playwright.Locator, resolved: string, selector: string }[]> {
await this._initializedPromise;
return Promise.all(params.map(async param => {
if (!param.target.match(/^(f\d+)?e\d+$/)) {
const selector = locatorOrSelectorAsSelector('javascript', param.target, this.context.config.testIdAttribute || 'data-testid');
const handle = await this.page.$(selector);
if (!handle)
throw new Error(`"${param.target}" does not match any elements.`);
handle.dispose().catch(() => {});
return { locator: this.page.locator(selector), resolved: asLocator('javascript', selector), selector };
} else {
try {
let locator = this.page.locator(`aria-ref=${param.target}`);
if (param.element)
locator = locator.describe(param.element);
const resolved = await locator.normalize();
return { locator, resolved: resolved.toString(), selector: locatorSelector(resolved) };
} catch (e) {
throw new Error(`Ref ${param.target} not found in the current page snapshot. Try capturing new snapshot.`);
}
}
}));
}
async waitForTimeout(time: number) {
if (this._javaScriptBlocked()) {
await new Promise(f => setTimeout(f, time));
return;
}
await this.page.evaluate(ms => new Promise(f => setTimeout(f, ms)), time).catch(() => {});
}
}
export type ConsoleMessage = {
type: ReturnType<playwright.ConsoleMessage['type']>;
timestamp: number;View on GitHub (pinned to c8fc3bf8d3)
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.
Example fix
// before
// snapshot taken 5 turns ago returned ref 'e7'; DOM since changed
await client.callTool('browser_click', { element: 'submit', target: 'e7' }); // throws
// after
await client.callTool('browser_snapshot', {});
// new ref 'e9'
await client.callTool('browser_click', { element: 'submit', target: 'e9' }); Defensive patterns
Strategy: retry
Validate before calling
function looksLikeRef(target: string): boolean {
return /^(f\d+)?e\d+$/.test(target);
}
function refAge(snapshotTurn: number, currentTurn: number): number {
return currentTurn - snapshotTurn;
} Type guard
function isStaleRefError(e: unknown): boolean {
return e instanceof Error && /Ref .* not found in the current page snapshot/.test(e.message);
} Try / catch
for (let attempt = 0; attempt < 2; attempt++) {
try {
await client.callTool('browser_click', { element, target: ref });
break;
} catch (e) {
if (isStaleRefError(e) && attempt === 0) {
await client.callTool('browser_snapshot', {});
// update `ref` from the new snapshot; continue
} else throw e;
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- "${param.target}" does not match any elements.
- Conflicting exactness in internal:role selector: ${stringify
- Unable to generate locator for ${selector}
- Selector "${selector}" does not match any element
- Video recording has already been started.
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/84dd7e3095253f72.
Report an issue: GitHub.