## TL;DR

Strict mode means your locator matched more than one element and Playwright refused to guess. Make the locator unique with a role plus accessible name, scope it to a container, or use nth() as an explicit, documented choice.

## Error

```text
Error: strict mode violation: locator('[data-testid="submit"]') resolved to 2 elements:
    1) [button data-testid="submit"]Save[/button]
    2) [button data-testid="submit"]Save[/button]
```

## Steps

1. Read the error: it lists the matched elements. Expected: you see why there are two (duplicate component, hidden copy).
2. Prefer a role with a name: `page.getByRole('button', { name: 'Save changes' })`. Expected: the accessible name disambiguates.
3. If the page legitimately has two, scope to the container: `page.getByTestId('dialog').getByRole('button', { name: 'Save' })`. Expected: one match inside the scope.
4. If one copy is hidden (mobile/desktop duplicates), filter: `.first()` or check which is visible and target it explicitly. Expected: an intentional choice, not an accident.
5. Only use `.nth(1)` when the duplication is stable and documented in a comment. Expected: future readers know the index is deliberate.

## When to use

- The error says `strict mode violation`.
- The page renders the component twice (dialogs, responsive duplicates).

## When not to use

- The locator matches zero elements (timeout skill).
- You want to click all matches (use a loop over `.all()`, not a single locator).

## Tool compatibility

- Playwright 1.30 through latest; strict mode is on by default.

## Variant phrasings

### locator resolved to N elements

The general form; N tells you how ambiguous the locator is.

### getByRole strict mode violation

Even role locators can be ambiguous; add the name or scope.

## Why it happens

Playwright's strict mode prevents the classic Selenium bug of acting on the wrong duplicate. It forces you to say which element you mean.

## Edge cases

- `page.locator('...')` with CSS is the most common offender; role locators are stricter by construction.
- Hidden duplicates from responsive design are a testability smell; consider hiding them with `hidden` attributes.
- `.first()` on a list that reorders is flaky; prefer a stable identifier.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_Uu4aVjwhg4Fp7xUDrxozNA
