microsoft/playwright · error · Error
Unable to generate locator for ${selector}
Error message
Unable to generate locator for ${selector} What it means
Thrown by Frame.resolveSelector() when the generateSelectorSimple() injected script returns a falsy value for the matched element itself (not its parent frames). This means Playwright's selector generation engine could not produce a valid CSS/XPath selector for the element, which can happen with elements that lack distinguishing attributes or are in unusual DOM positions.
Source
Thrown at packages/playwright-core/src/server/frames.ts:1320
async focus(progress: Progress, selector: string, options: types.StrictOptions & { noAutoWaiting?: boolean }) {
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (progress, handle) => handle._focus(progress)));
}
async blur(progress: Progress, selector: string, options: types.StrictOptions & { noAutoWaiting?: boolean }) {
dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (progress, handle) => handle._blur(progress)));
}
async resolveSelector(progress: Progress, selector: string, options: { mainWorld?: boolean } = {}): Promise<{ resolvedSelector: string }> {
const element = await progress.race(this.selectors.query(selector, options));
if (!element)
throw new Error(`No element matching ${selector}`);
const generated = await progress.race(element.evaluateInUtility(async ([injected, node]) => {
return injected.generateSelectorSimple(node as unknown as Element);
}, {}));
if (!generated)
throw new Error(`Unable to generate locator for ${selector}`);
let frame: Frame | null = element._frame;
const result = [generated];
while (frame?.parentFrame()) {
const frameElement = await frame.frameElement(progress);
if (frameElement) {
const generated = await progress.race(frameElement.evaluateInUtility(async ([injected, node]) => {
return injected.generateSelectorSimple(node as unknown as Element);
}, {}));
frameElement.dispose();
if (generated === 'error:notconnected' || !generated)
throw new Error(`Unable to generate locator for ${selector}`);
result.push(generated);
}
frame = frame.parentFrame();
}
const resolvedSelector = result.reverse().join(' >> internal:control=enter-frame >> ');
return { resolvedSelector };View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Add a stable identifier (id, data-testid) to the element in the page's HTML so the generator can target it.
- Use a hand-written selector instead of relying on resolveSelector's auto-generation.
- If using MCP tools, specify the selector explicitly rather than relying on resolution.
Example fix
// before — element has no distinguishing attributes <button>Submit</button> // resolveSelector fails to generate a locator // after — add a data-testid <button data-testid="submit-btn">Submit</button>
Defensive patterns
Strategy: validation
Validate before calling
// Add data-testid to elements to ensure reliable selector generation // In page HTML: <div data-testid="my-element">
Try / catch
try {
await frame.resolveSelector(selector);
} catch (e) {
if (e.message.startsWith('Unable to generate locator')) {
// Provide a hand-crafted selector instead
return { resolvedSelector: manualSelector };
}
throw e;
} Prevention
- Add data-testid attributes to elements for stable selector generation.
- Provide explicit selectors instead of relying on auto-generation for complex DOMs.
- Ensure elements have distinguishing attributes (id, role, data-*).
When it happens
Trigger: Calling resolveSelector on an element that the selector generator cannot describe. This occurs when the element is deeply nested in a generic DOM structure with no unique attributes, or when the element's structure is too dynamic for the generator to produce a stable selector.
Common situations: Element is a bare <div> or <span> with no id, class, or data attributes among many siblings. Shadow DOM or custom elements that confuse the generator. Element was detached between the query and the generateSelector call.
Related errors
- No element matching ${selector}
- Conflicting exactness in internal:role selector: ${stringify
- Frame has been detached.
- Unable to retrieve content because the page is navigating an
- Provide an object with a `url`, `path` or `content` property
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/03c84755c907f112.
Report an issue: GitHub.