{"record":{"id":"3db4891d89570e92","repo":"microsoft/playwright","slug":"unable-to-serialize-indexeddb-e-message","errorCode":null,"errorMessage":"Unable to serialize IndexedDB: ${e.message}","messagePattern":"Unable to serialize IndexedDB: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/injected/src/storageScript.ts","lineNumber":183,"sourceCode":"        const base64 = typedArrayToBase64(new Uint8Array(await file.arrayBuffer()));\n        return [{ path, type: 'file', base64 }];\n      }));\n      return results.flat();\n    };\n    return collect(root, '');\n  }\n\n  async collect(record: { indexedDB: boolean, opfs: boolean }): Promise<SerializedStorage> {\n    const localStorage = Object.keys(this._global.localStorage)\n        .filter(name => !name.startsWith(kCoverageStashPrefix))\n        .map(name => ({ name, value: this._global.localStorage.getItem(name)! }));\n    const result: SerializedStorage = { localStorage };\n    if (record.indexedDB) {\n      try {\n        const databases = await this._global.indexedDB.databases();\n        result.indexedDB = await Promise.all(databases.map(db => this._collectDB(db)));\n      } catch (e) {\n        throw new Error('Unable to serialize IndexedDB: ' + e.message);\n      }\n    }\n    if (record.opfs) {\n      try {\n        result.opfs = await this._collectOPFS(await this._global.navigator.storage.getDirectory());\n      } catch (e) {\n        throw new Error('Unable to serialize OPFS: ' + e.message);\n      }\n    }\n    return result;\n  }\n\n  private async _restoreDB(dbInfo: IndexedDBDatabase) {\n    const openRequest = this._global.indexedDB.open(dbInfo.name, dbInfo.version);\n    openRequest.addEventListener('upgradeneeded', () => {\n      const db = openRequest.result;\n      for (const store of dbInfo.stores) {\n        const objectStore = db.createObjectStore(store.name, { autoIncrement: store.autoIncrement, keyPath: store.keyPathArray ?? store.keyPath });","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/microsoft/playwright/blob/f1d33b5029be8bbc1095fe88e559117fa3a6243b/packages/injected/src/storageScript.ts#L165-L201","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Close all other connections to the affected IndexedDB database before capturing state, since a pending versionchange blocks indexedDB.open and times out the collection.","Retry the collection after a short delay; transient open/upgrade failures often resolve once competing connections release the database.","Catch this error at the caller and skip or stub the indexedDB portion of SerializedStorage when IndexedDB access is unavailable (partitioned contexts, unsupported browsers).","Check the wrapped e.message for QuotaExceededError and free origin storage or reduce collected data before retrying.","Verify the page origin matches the database origin; cross-origin or about:blank frames have no accessible IndexedDB."],"exampleFix":"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.","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid holding long-lived open connections or triggering version upgrades while storage snapshots are being collected.","Run storage collection in a context with granted storage access and sufficient quota.","Treat IndexedDB capture as best-effort in consumers so a single database failure does not abort the whole snapshot."],"tags":[],"backgroundTag":null,"analyzedSha":"f1d33b5029be8bbc1095fe88e559117fa3a6243b","analyzedAt":"2026-09-07T14:42:43.271Z","contentChangedAt":"2026-09-07T14:42:43.271Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}