microsoft/playwright · error · Error

Unable to serialize IndexedDB

Error message

Unable to serialize IndexedDB: ${e.message}

What it means

Raised in SerializedStorage.collect() when IndexedDB snapshot collection fails. This is a generic guard: the try/catch around indexedDB.databases() and _collectDB() re-wraps ANY underlying failure (open request error, upgrade/transaction failure, blocked database, quota exceeded, or a page-side IndexedDB exception) into a single Error prefixed with 'Unable to serialize IndexedDB:'. It fires when record.indexedDB is true and any enumeration, open, or read of the origin's databases throws or rejects.

Solutions

  1. Close all other connections to the affected IndexedDB database before capturing state, since a pending versionchange blocks indexedDB.open and times out the collection.
  2. Retry the collection after a short delay; transient open/upgrade failures often resolve once competing connections release the database.
  3. Catch this error at the caller and skip or stub the indexedDB portion of SerializedStorage when IndexedDB access is unavailable (partitioned contexts, unsupported browsers).
  4. Check the wrapped e.message for QuotaExceededError and free origin storage or reduce collected data before retrying.
  5. Verify the page origin matches the database origin; cross-origin or about:blank frames have no accessible IndexedDB.

Example fix

In tests, close all other connections to the database (or use a fresh context/database name) before triggering state capture so the open request is not blocked. Handle the error at the caller by degrading gracefully — skip the indexedDB entry instead of failing the whole capture when the source page denies access.
Defensive patterns

Strategy: try-catch

Prevention

When it happens

Trigger: A database cannot be opened or read during snapshot collection (blocked or version-change deadlock, corrupt DB, storage quota exceeded, or access denied in a partitioned/third-party context); indexedDB.databases() is unsupported or throws; or _collectDB's transaction/read of stores fails mid-enumeration.

Common situations: Capturing storage state for test assertions or trace snapshots on a page where the target database is open elsewhere with a pending versionchange (open request blocks), when the origin is in a partitioned storage context that denies IndexedDB access, or when the origin's storage is evicted or over quota during collection.


AI-assisted analysis of microsoft/playwright@f1d33b5029 (2026-09-07). Data as JSON: /api/errors/3db4891d89570e92. Report an issue: GitHub.

Appendix: source

Thrown at packages/injected/src/storageScript.ts:183

        const base64 = typedArrayToBase64(new Uint8Array(await file.arrayBuffer()));
        return [{ path, type: 'file', base64 }];
      }));
      return results.flat();
    };
    return collect(root, '');
  }

  async collect(record: { indexedDB: boolean, opfs: boolean }): Promise<SerializedStorage> {
    const localStorage = Object.keys(this._global.localStorage)
        .filter(name => !name.startsWith(kCoverageStashPrefix))
        .map(name => ({ name, value: this._global.localStorage.getItem(name)! }));
    const result: SerializedStorage = { localStorage };
    if (record.indexedDB) {
      try {
        const databases = await this._global.indexedDB.databases();
        result.indexedDB = await Promise.all(databases.map(db => this._collectDB(db)));
      } catch (e) {
        throw new Error('Unable to serialize IndexedDB: ' + e.message);
      }
    }
    if (record.opfs) {
      try {
        result.opfs = await this._collectOPFS(await this._global.navigator.storage.getDirectory());
      } catch (e) {
        throw new Error('Unable to serialize OPFS: ' + e.message);
      }
    }
    return result;
  }

  private async _restoreDB(dbInfo: IndexedDBDatabase) {
    const openRequest = this._global.indexedDB.open(dbInfo.name, dbInfo.version);
    openRequest.addEventListener('upgradeneeded', () => {
      const db = openRequest.result;
      for (const store of dbInfo.stores) {
        const objectStore = db.createObjectStore(store.name, { autoIncrement: store.autoIncrement, keyPath: store.keyPathArray ?? store.keyPath });

View on GitHub (pinned to f1d33b5029)