Skip to content

[Bug] [Python] StorageState TypedDict doesn't have credentials and opfs entries #42732

Closed as not planned

Description

Version

1.63.0

Steps to reproduce

The StorageState TypedDict doesn't have optional entries for opfs and credentials, which causes problems with typing.

https://github.com/microsoft/playwright-python/blob/40f75509e096eab5c156109b6fd51a978e410016/playwright/_impl/_api_structures.py#L112

Expected behavior

storage state with relevant entries

Actual behavior

Use dict and ignore typing

playwrightcapture/capture.py: note: In member "initialize_context" of class "Capture":
playwrightcapture/capture.py:706: error: Argument "storage_state" to "new_context" of "Browser" has
incompatible type "dict[str, Any] | None"; expected "StorageState | str | Path | None"  [arg-type]
                storage_state=self.storage if self.storage else None,
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
playwrightcapture/capture.py: note: In member "_finalize_capture" of class "Capture":
playwrightcapture/capture.py:1250: error: Value of "storage" has incompatible type "StorageState";
expected "dict[str, Any] | None"  [typeddict-item]
                    to_return['storage'] = await self.context.storage_state(indexed_db=True,
                                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Found 2 errors in 1 file (checked 8 source files)

Additional context

No response

Environment

System:
   OS: Linux 7.0 Ubuntu 26.04.1 LTS 26.04.1 LTS (Resolute Raccoon)
   CPU: (8) x64 Intel(R) Core(TM) i7-8665U CPU @ 1.90GHz
   Memory: 9.66 GB / 31.00 GB
   Container: Yes
 Binaries:
   Node: 22.22.1 - /usr/bin/node
   npm: 9.2.0 - /usr/bin/npm
 Languages:
   Bash: 5.3.9 - /usr/bin/bash

Activity

  1. shubhambhar007 commented on Sep 15, 2026

    @shubhambhar007

    Raphaël Vinot (@Rafiot) could you please assign this to me ,thanks! - raised PR microsoft/playwright-python#3201

  2. github-actions commented on Sep 15, 2026

    @github-actions
    Contributor

    Hi, I'm the Playwright bot and I took a first look at this.

    Confirmed, and it's wider than the Python StorageState TypedDict — the declared storage state shape is stale in every language, because it's generated from the docs in this repo and those were never updated when the new options landed. BrowserContext.storageState() returns more than the type admits:

    • indexedDB per origin (option added in 1.51)
    • opfs per origin (1.63)
    • top-level credentials (1.61)

    The server fills all three in (browserContext.ts#L617-L632 — result.credentials = ... and script.collect({ indexedDB, opfs })), but the documented return type is still just cookies + origins.localStorage. Same on the input side, so a storageState(...) → newContext({ storageState }) round trip doesn't type-check against what it actually produces.

    So the Python fix needs the docs change here first, otherwise it drifts right back.

    Where the type is declared

    Source of truth (docs), both missing the new fields:

    Which generates the equally stale types.d.ts:

    // packages/playwright-core/types/types.d.ts — BrowserContext.storageState()
    }): Promise<{
      cookies: Array<{ name: string; value: string; domain: string; path: string;
        expires: number; httpOnly: boolean; secure: boolean; sameSite: "Strict"|"Lax"|"None"; }>;
      origins: Array<{
        origin: string;
        localStorage: Array<{ name: string; value: string }>;
        // no indexedDB, no opfs
      }>;
      // no credentials
    }>;

    The client-side type does the omission explicitly, which is where the asymmetry shows up:

    // packages/playwright-core/src/client/types.ts
    export type StorageState = {
      cookies: channels.NetworkCookie[],
      origins: (Omit<channels.OriginStorage, 'indexedDB'>)[],
    };
    export type SetStorageState = {
      cookies?: channels.SetNetworkCookie[],
      origins?: (Omit<channels.SetOriginStorage, 'indexedDB'> & { indexedDB?: unknown[] })[],
      credentials?: unknown[],
    };

    And the Python mirror you linked, StorageState / OriginState in playwright/_impl/_api_structures.py, has the same two fields and nothing else.

    What I checked
    • tip-of-tree microsoft/playwright @ 9ae5377 — docs, generated types.d.ts, client types, server storageState() implementation
    • microsoft/playwright-python @ 40f7550 (the sha you linked) — _api_structures.py
    • no runtime repro run: this is a static typing gap, the values are present at runtime and the declaration is what's short

    One thing worth splitting out: indexedDB, opfs and credentials are opt-in, so they're optional keys on the emitted state — whether the type marks them optional or always-present changes how mypy treats the round trip, and that's a call for a maintainer.

    Triaged on Linux by the Playwright bot - agent run

  3. dcrousso commented on Sep 19, 2026

    @dcrousso
    Contributor

    the incomplete storage state type is intentional microsoft/playwright-python#3094 (comment)

    for an unchanged round trip, use StorageState for both your stored value and result field rather than dict[str, Any]

    if you need to access the additional fields, define a local type and cast as suggested in microsoft/playwright-python#2796 (comment)

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions