Skip to content

[Bug]: Request.post_data_json raises KeyError when content-type is missing #3093

Closed

Description

Version

main branch source as of 2026-06-08 (latest release is 1.60.0)

Steps to reproduce

Request.post_data_json currently assumes every request with a post body has a content-type header.

A minimal source-level reproduction against the current repo:

import base64
import sys
import types

repo_version = types.ModuleType("playwright._repo_version")
repo_version.version = "0.0.0-test"
sys.modules["playwright._repo_version"] = repo_version

from playwright._impl._network import RawHeaders, Request, SerializedFallbackOverrides

req = Request.__new__(Request)
req._initializer = {
    "url": "https://example.test/",
    "method": "POST",
    "resourceType": "xhr",
    "headers": [],
    "postData": base64.b64encode(b'{"a": 1}').decode(),
}
req._fallback_overrides = SerializedFallbackOverrides()
req._provisional_headers = RawHeaders(req._initializer["headers"])

print(req.post_data_json)

Expected behavior

request.post_data_json should treat the missing content-type header as "not form-urlencoded" and then use the documented JSON fallback. For the body above, it should return {"a": 1}.

This matches the upstream JavaScript implementation, which checks the header with optional access before the form-urlencoded branch.

Actual behavior

The property raises before it reaches JSON parsing:

KeyError: 'content-type'

The source currently does this:

content_type = self.headers["content-type"]
if "application/x-www-form-urlencoded" in content_type:
    ...

Additional context

The API docs say Request.post_data_json returns parsed form-urlencoded data and parses JSON as a fallback. A missing content-type header should not prevent that fallback path.

Activity

  1. rohan-patnaik commented on Jun 8, 2026

    @rohan-patnaik
    ContributorAuthor

    Potential fix direction I'm thinking of raising a PR for ->

    In playwright/_impl/_network.py, read the header defensively, for example:

    content_type = self.headers.get("content-type")
    if content_type and "application/x-www-form-urlencoded" in content_type:
        return dict(parse.parse_qsl(post_data))

    Then add a focused regression test for a request that has a JSON body but no content-type header, asserting that request.post_data_json returns the parsed JSON instead of raising KeyError.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions