actualbudget/actual · critical · Error
indexeddb-quota-error
indexeddb-quota-error
Error message
indexeddb-quota-error
What it means
When Actual runs in the browser it persists data to IndexedDB. During database use, an IDB 'QuotaExceededError' means the browser cannot allocate more storage for the database. Actual rethrows this as the coded error 'indexeddb-quota-error' so callers can distinguish storage exhaustion from other database failures.
Source
Thrown at packages/loot-core/src/platform/server/indexeddb/index.ts:52
logger.log('openRequest error');
reject(new Error('indexeddb-failure: Could not open IndexedDB'));
};
openRequest.onsuccess = function (e) {
const db = (e.target as IDBOpenDBRequest).result;
db.onversionchange = () => {
// TODO: Notify the user somehow
db.close();
};
db.onerror = function (event) {
const error = (event.target as IDBOpenDBRequest)?.error;
logger.log('Database error:', error);
if (event.target && error) {
if (error.name === 'QuotaExceededError') {
throw new Error('indexeddb-quota-error');
}
}
};
resolve(db);
};
});
}
type Data = { filepath: string; contents: string };
export const getStore = function (db: IDBDatabase, name: string) {
const trans = db.transaction([name], 'readwrite');
return { trans, store: trans.objectStore(name) };
};
export const get = async function (
store: IDBObjectStore,
key: IDBValidKey | IDBKeyRange,View on GitHub (pinned to d4334cb6e6)
Solutions
- Free up storage: clear other site data, or free disk space, then retry the operation.
- Switch to a sync-server-backed setup (file/SQLite storage) instead of relying on IndexedDB persistence.
- Export/back up the budget, then prune large attachments or old transactions to shrink the database.
- Retry in a normal (non-private) browser window or a browser with a higher storage quota.
Example fix
// before
await openDatabase();
// after
try {
await openDatabase();
} catch (e) {
if (e.message === 'indexeddb-quota-error') {
alert('Browser storage is full. Free up space or switch to a server-backed budget.');
} else {
throw e;
}
} Defensive patterns
Strategy: try-catch
Validate before calling
if (navigator.storage && navigator.storage.estimate) {
const { usage, quota } = await navigator.storage.estimate();
if (quota && usage / quota > 0.9) {
console.warn('Storage nearly full; IndexedDB writes may fail');
}
} Type guard
function isIndexeddbQuotaError(e: unknown): e is Error {
return e instanceof Error && e.message === 'indexeddb-quota-error';
} Try / catch
try {
await openDatabase();
} catch (e) {
if (isIndexeddbQuotaError(e)) {
showStorageFullDialog(); // offer export / server sync
} else {
throw e;
}
} Prevention
- Monitor navigator.storage.estimate() and warn users before quota runs out.
- Encourage server-sync setups for large budgets.
- Prune attachments and old transactions periodically.
- Avoid private-browsing modes for long-term data entry.
When it happens
Trigger: Any IndexedDB write/open while the browser's storage quota is exhausted — large budgets, many downloaded files stored in the DB, private/incognito browsing modes with tiny quotas, or a disk nearly full on the host machine.
Common situations: Users syncing big budgets on mobile browsers with strict per-origin quotas; running Actual in Firefox private windows; Chromium profiles with cleared or capped site-data; shared machines with full disks.
Related errors
- Geolocation is not supported by this browser
- File does not exist: ${filepath}
- Invalid upload filename
- Persistent storage request failed:
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/4daaade4802f6e3c.
Report an issue: GitHub.