You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: routeFromHAR fails with "Specified archive does not have a .har file" when inner zip entry has uppercase .HAR extension #43669
Create a zip archive archive.har.zip containing a valid HAR file, but named with uppercase extension (e.g. Recording.HAR or session.Har from DevTools / external tools).
Call context.routeFromHAR on the zip file:
import{test,expect}from'@playwright/test';test('repro uppercase har entry in zip',async({ context })=>{// archive.har.zip holds a valid HAR entry named "Recording.HAR"awaitcontext.routeFromHAR('archive.har.zip');});
### ExpectedbehaviorTheHARarchiveshouldreplaysuccessfullyregardlessofinnerentrycasing,matchingthecase-insensitive.zipextensionhandlingintroducedin #43550.
### Actualbehavior
Fails with:
Error: Specifiedarchivedoesnothavea.harfileThisoccursbecauselocalUtils.tsusesentryNames.find(e=>e.endsWith('.har'))case-sensitively,sovalidarchiveswithentrieslikeRecording.HARorsession.Hararerejected.
### AdditionalcontextThisistheinner-entrycounterpartto #43550(`fix(har): recognize .zip extensions regardless of case`).While #43550madethearchivefileextensioncase-insensitive,theentrynamechecksinside`packages/playwright-core/src/server/localUtils.ts`remainedcase-sensitive:
```diff
diff --git a/packages/playwright-core/src/server/localUtils.ts b/packages/playwright-core/src/server/localUtils.ts
index df62972b2..2be37ea7a 100644
--- a/packages/playwright-core/src/server/localUtils.ts
+++ b/packages/playwright-core/src/server/localUtils.ts
@@ -153,7 +153,7 @@ export async function harOpen(progress: Progress, harBackends: Map<string, HarBa
const zipFile = new ZipFile(params.file);
try {
const entryNames = await progress.race(zipFile.entries());
- const harEntryName = entryNames.find(e => e.endsWith('.har'));
+ const harEntryName = entryNames.find(e => /\.har$/i.test(e));
if (!harEntryName)
return { error: 'Specified archive does not have a .har file' };
const har = await progress.race(zipFile.read(harEntryName));
@@ -193,7 +193,7 @@ export async function harUnzip(progress: Progress, params: channels.LocalUtilsHa
try {
for (const entry of await progress.race(zipFile.entries())) {
const buffer = await progress.race(zipFile.read(entry));
- if (entry === 'har.har') {
+ if (/^har\.har$/i.test(entry)){awaitprogress.race(fs.promises.writeFile(params.harFile,buffer));}else{if(!resourcesDirCreated){
i already have this patch and a passing test (HA-114 in tests/library/browsercontext-har.spec.ts) verified locally against the full test suite (101 HAR tests passing).
If community PRs are welcome for this, i would be very happy to submit the PR! Alternatively, if the core team / triage bot prefers handling it directly like in #43550, please feel free to pick up the diff above.
Environment
System:
OS: macOS 15.5
CPU: (10) arm64 Apple M1 Max
Binaries:
Node: 22.22.3
npm: 10.9.8
npmPackages:
playwright: latest
Hi, I'm the Playwright bot and I reproduced this on Linux.
Reproduced on 1.65.0-next (1b9b602724484df3ebc41aba77824fdfaba861f6) in Chromium, Firefox, and WebKit. The archive opens, but harOpen checks the inner .har extension case-sensitively. A verified fix makes that check case-insensitive while preserving the original entry name when reading the file.
Reproduction and verification
The regression extends the existing HA-085 should round-trip har.zip test: record and replay the lowercase HAR, then repack the same archive with har.har renamed to Recording.HAR, retaining all response-body files, and replay it again. It checks both the HTML body and the stylesheet.
Before the fix, the second context.routeFromHAR() call failed with Specified archive does not have a .har file on all three browsers. With the fix, the HAR suites passed.
Before fix: npm run test -- tests/library/browsercontext-har.spec.ts --grep HA-085 --workers=3 --retries=0 --reporter=line — 3 failures with the reported error.
After fix: npm run test -- tests/library/browsercontext-har.spec.ts tests/library/har.spec.ts tests/library/har-websocket.spec.ts --workers=3 --retries=0 --reporter=dot — 336 passed, 6 skipped.
npm run build and npm run flint passed.
The proposed fix does not change harUnzip: that internal extraction path receives Playwright-generated archives, whose HAR entry is always named har.har.
Activity
github-actions commentedon Oct 28, 2026
github-actions commentedon Oct 28, 2026
Hi, I'm the Playwright bot and I reproduced this on Linux.
Reproduced on
1.65.0-next(1b9b602724484df3ebc41aba77824fdfaba861f6) in Chromium, Firefox, and WebKit. The archive opens, butharOpenchecks the inner.harextension case-sensitively. A verified fix makes that check case-insensitive while preserving the original entry name when reading the file.Reproduction and verification
The regression extends the existing
HA-085 should round-trip har.ziptest: record and replay the lowercase HAR, then repack the same archive withhar.harrenamed toRecording.HAR, retaining all response-body files, and replay it again. It checks both the HTML body and the stylesheet.Before the fix, the second
context.routeFromHAR()call failed withSpecified archive does not have a .har fileon all three browsers. With the fix, the HAR suites passed.npm run test -- tests/library/browsercontext-har.spec.ts --grep HA-085 --workers=3 --retries=0 --reporter=line— 3 failures with the reported error.npm run test -- tests/library/browsercontext-har.spec.ts tests/library/har.spec.ts tests/library/har-websocket.spec.ts --workers=3 --retries=0 --reporter=dot— 336 passed, 6 skipped.npm run buildandnpm run flintpassed.The proposed fix does not change
harUnzip: that internal extraction path receives Playwright-generated archives, whose HAR entry is always namedhar.har.Draft fix: #43725
Triaged on Linux by the Playwright bot - agent run