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
- 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.
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
- 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.
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)