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]: WebKit decodes HTML from route.fulfill() as windows-1252, ignoring charset=utf-8 #43649
[ 'UTF-8', '₹' ], as in Chromium and Firefox, and as WebKit gives when a real HTTP server sends the same Content-Type: text/html; charset=utf-8 header.
Actual behavior
[ 'windows-1252', '₹' ]. It's the same with headers: { "Content-Type": "text/html; charset=utf-8" } instead of contentType, with a Buffer body, and with text/html;charset=UTF-8.
We hit this in a test whose fulfilled page embeds a srcdoc iframe containing an inline script with non-ASCII text, allowed by a CSP sha256- hash. Incorrect decoding of the outer page changed the iframe's script text, so its hash no longer matched and WebKit refused to run it. Adding <meta charset="utf-8"> to the fulfilled page works around it.
I was able to reproduce this on Windows with playwright-core@1.64.1 and WebKit 27.2.
I get: [ 'windows-1252', '₹' ]
I'd like to try working on a fix. Before I start digging into the code, could a maintainer confirm whether this issue is open for community contributions and whether the fix would likely belong in Playwright's TypeScript code or the patched WebKit engine?
Hi, I'm the Playwright bot and I reproduced this on Windows.
Reproduced on current main, only in WebKit. The browser's interception handler discards the supplied charset: it replaces Content-Type with the bare MIME type and leaves the response's text encoding empty. This needs a WebKit engine change, not just a TypeScript change. Adding <meta charset="utf-8"> works around it.
Reproduction and results
Tested Playwright 1.65.0-next, commit e478109de5542aa6bd69f817d6cb054523af9ce4, on Windows:
The reported releases were not separately tested; this reproduces on main. Linux and macOS were not tested in this Windows run.
The regression fits the existing RO-096 should work test in tests/page/page-request-fulfill.spec.ts:
it('RO-096 should work',{annotation: {type: 'issue',description: 'https://github.com/microsoft/playwright/issues/43649'},},async({ page, server })=>{awaitpage.route('**/*',route=>route.fulfill({status: 201,headers: {foo: 'bar'},contentType: 'text/html; charset=utf-8',body: '<!doctype html><p>\u20b9</p>',}));constresponse=awaitpage.goto(server.EMPTY_PAGE);expect(response.status()).toBe(201);expect(response.headers().foo).toBe('bar');expect(awaitpage.evaluate(()=>[document.characterSet,document.querySelector('p').textContent])).toEqual(['UTF-8','\u20b9']);});
WebKit returns ['windows-1252', '\u00e2\u201a\u00b9']. Its received response header is text/html; Chromium and Firefox retain text/html;charset=UTF-8. Protocol logging confirms Playwright sent the full charset-bearing header to WebKit.
Commands:
npm run test -- page-request-fulfill.spec.ts --grep RO-096 --workers=3 --reporter=line
npm run test -- page-request-fulfill.spec.ts --grep RO-096 --headed --retries=0 --workers=3 --reporter=line
npm run test -- page-request-fulfill.spec.ts --grep RO-096 --retries=0 --workers=3 --reporter=line
The last command included the HTTP, Buffer/header and meta-tag controls. A further WebKit-only run of those controls used DEBUG=pw:protocol with npm run wtest -- page-request-fulfill.spec.ts --grep RO-096 --retries=0 --reporter=line. Both faulty fulfillment cases failed; the HTTP and meta-tag controls passed. The initial headless regression failed on all four WebKit attempts, including retries.
Engine fix location
InspectorNetworkAgent::interceptRequestWithResponse constructs ResourceResponse with an empty encoding, copies the supplied headers, then overwrites Content-Type with response.mimeType(). Playwright's browser_patches/webkit/patches/bootstrap.diff keeps those lines.
The suggested engine fix is to preserve the explicit Content-Type (using the MIME type only as a fallback) and populate ResourceResponse::textEncodingName from its charset, using WebKit's extractCharsetFromMediaType helper. Changing only the TypeScript mimeType value would not populate the encoding field.
No engine build or engine-fix verification was attempted in this workflow.
Triaged on Windows by the Playwright bot - agent run
Activity
Ayush-S-inha commentedon Oct 26, 2026
I was able to reproduce this on Windows with
playwright-core@1.64.1and WebKit 27.2.I get: [ 'windows-1252', '₹' ]
I'd like to try working on a fix. Before I start digging into the code, could a maintainer confirm whether this issue is open for community contributions and whether the fix would likely belong in Playwright's TypeScript code or the patched WebKit engine?
I haven't made any source changes yet.
github-actions commentedon Oct 26, 2026
Hi, I'm the Playwright bot and I reproduced this on Windows.
Reproduced on current main, only in WebKit. The browser's interception handler discards the supplied charset: it replaces
Content-Typewith the bare MIME type and leaves the response's text encoding empty. This needs a WebKit engine change, not just a TypeScript change. Adding<meta charset="utf-8">works around it.Reproduction and results
Tested Playwright
1.65.0-next, commite478109de5542aa6bd69f817d6cb054523af9ce4, on Windows:Content-Type: text/html;charset=UTF-8, headlessThe reported releases were not separately tested; this reproduces on main. Linux and macOS were not tested in this Windows run.
The regression fits the existing
RO-096 should worktest intests/page/page-request-fulfill.spec.ts:WebKit returns
['windows-1252', '\u00e2\u201a\u00b9']. Its received response header istext/html; Chromium and Firefox retaintext/html;charset=UTF-8. Protocol logging confirms Playwright sent the full charset-bearing header to WebKit.Commands:
The last command included the HTTP, Buffer/header and meta-tag controls. A further WebKit-only run of those controls used
DEBUG=pw:protocolwithnpm run wtest -- page-request-fulfill.spec.ts --grep RO-096 --retries=0 --reporter=line. Both faulty fulfillment cases failed; the HTTP and meta-tag controls passed. The initial headless regression failed on all four WebKit attempts, including retries.Engine fix location
InspectorNetworkAgent::interceptRequestWithResponseconstructsResourceResponsewith an empty encoding, copies the supplied headers, then overwritesContent-Typewithresponse.mimeType(). Playwright'sbrowser_patches/webkit/patches/bootstrap.diffkeeps those lines.The suggested engine fix is to preserve the explicit
Content-Type(using the MIME type only as a fallback) and populateResourceResponse::textEncodingNamefrom its charset, using WebKit'sextractCharsetFromMediaTypehelper. Changing only the TypeScriptmimeTypevalue would not populate the encoding field.No engine build or engine-fix verification was attempted in this workflow.
Triaged on Windows by the Playwright bot - agent run
dgozman commentedon Oct 28, 2026
🛑 Blocked on upstream issue https://github.com/microsoft/playwright-browsers/issues/2623