microsoft / microsoft/playwright

[Bug]: When aborting only first request with {times: 1} from page route then the second request randomly failed

Open
#41,802 2 comments 1 reaction 1 assignee View on GitHub

@dgozman is already working on this.

Since Jul 16, 2026.

browser-chromium upstream v1.64
Dominant language
TypeScript
Stars
96.3k
Forks
6.5k
Avg merge
1d 6h
Merged PRs (30d)
180

Description

### Version

1.56.1

### Steps to reproduce

1. Clone my repo at https://github.com/jesabot-cmyk/testPlaywrightIssue
2. npm install
3. then npm run test (it will perform 10 runs from playwirght config)
4. You should see most of runs pass but a few are failing and falling to the hung issue

Here the minimal code to reproduce the bug and figure out what is happening:

```
import { test, expect } from '@playwright/test';

test('route abort { times: 1 } - 2nd sequential fetch should not be affected', async ({ page }) => {
await page.goto('/');

await page.route('**/data', (route) => route.abort('timedout'), { times: 1 });

const results = await page.evaluate(async () => {
// Race each fetch against a 3s timeout to distinguish 'hung' from '200' or 'aborted'.
// 'hung' = { times: 1 } captured the request but never resolved it (orphaned).
async function fetchOrHung(url: string) {
const timeout = new Promise(resolve => setTimeout(() => resolve('hung'), 3000));
const request = fetch(url).then(r => String(r.status)).catch(() => 'aborted');
return Promise.race([request, timeout]);
}
const first = await fetchOrHung('/data'); // awaited — 2nd fetch only starts after 1st completes
const second = await fetchOrHung('/data');
return [first, second];
});

console.log('results:', results);
// Expected: ['aborted', '200']
// Bug: ['aborted', 'hung'] ← { times: 1 } captured the 2nd request but orphaned it

expect(results[0]).toBe('aborted');
expect(results[1]).toBe('200');
});
```

### Expected behavior

Request 1: is caught by the { times: 1 } handler and abort
Requests 2+: is not caught and succeed with status 200

### Actual behavior

Request 1: is caught by the { times: 1 } handler and abort
Requests 2+: is caught and fail

### Additional context

Random issue so many runs are required to reproduce and observe bug.
Workaround Applied (Stable): Replace { times: 1 } with manual flag-based counting:

```
let alreadyAborted = false;
await page.route('**/endpoint', async (route) => {
if (alreadyAborted) {
return route.continue();
}
alreadyAborted = true;
return route.abort('timedout');
});
```
This workaround is stable and reliable.

### Environment

```shell
System:
OS: Linux 6.18 Ubuntu 24.04.3 LTS 24.04.3 LTS (Noble Numbat)
CPU: (32) x64 13th Gen Intel(R) Core(TM) i9-13950HX
Memory: 19.74 GB / 31.19 GB
Container: Yes
Binaries:
Node: 20.19.5 - /home/sabotje/.nvm/versions/node/v20.19.5/bin/node
npm: 10.8.2 - /home/sabotje/.nvm/versions/node/v20.19.5/bin/npm
pnpm: 9.15.9 - /home/sabotje/.nvm/versions/node/v20.19.5/bin/pnpm
IDEs:
VSCode: 1.128.1 - /home/sabotje/.vscode-server/bin/5264f2156cbcd7aea5fd004d29eaa10209155d66/bin/remote-cli/code
Languages:
Bash: 5.2.21 - /usr/bin/bash
npmPackages:
@playwright/test: ^1.56.1 => 1.61.1
```

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.