{"record":{"id":"4daaade4802f6e3c","repo":"actualbudget/actual","slug":"indexeddb-quota-error","errorCode":"indexeddb-quota-error","errorMessage":"indexeddb-quota-error","messagePattern":"indexeddb-quota-error","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/loot-core/src/platform/server/indexeddb/index.ts","lineNumber":52,"sourceCode":"      logger.log('openRequest error');\n      reject(new Error('indexeddb-failure: Could not open IndexedDB'));\n    };\n\n    openRequest.onsuccess = function (e) {\n      const db = (e.target as IDBOpenDBRequest).result;\n\n      db.onversionchange = () => {\n        // TODO: Notify the user somehow\n        db.close();\n      };\n\n      db.onerror = function (event) {\n        const error = (event.target as IDBOpenDBRequest)?.error;\n        logger.log('Database error:', error);\n\n        if (event.target && error) {\n          if (error.name === 'QuotaExceededError') {\n            throw new Error('indexeddb-quota-error');\n          }\n        }\n      };\n      resolve(db);\n    };\n  });\n}\n\ntype Data = { filepath: string; contents: string };\n\nexport const getStore = function (db: IDBDatabase, name: string) {\n  const trans = db.transaction([name], 'readwrite');\n  return { trans, store: trans.objectStore(name) };\n};\n\nexport const get = async function (\n  store: IDBObjectStore,\n  key: IDBValidKey | IDBKeyRange,","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/loot-core/src/platform/server/indexeddb/index.ts#L34-L70","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait openDatabase();\n\n// after\ntry {\n  await openDatabase();\n} catch (e) {\n  if (e.message === 'indexeddb-quota-error') {\n    alert('Browser storage is full. Free up space or switch to a server-backed budget.');\n  } else {\n    throw e;\n  }\n}","handlingStrategy":"try-catch","validationCode":"if (navigator.storage && navigator.storage.estimate) {\n  const { usage, quota } = await navigator.storage.estimate();\n  if (quota && usage / quota > 0.9) {\n    console.warn('Storage nearly full; IndexedDB writes may fail');\n  }\n}","typeGuard":"function isIndexeddbQuotaError(e: unknown): e is Error {\n  return e instanceof Error && e.message === 'indexeddb-quota-error';\n}","tryCatchPattern":"try {\n  await openDatabase();\n} catch (e) {\n  if (isIndexeddbQuotaError(e)) {\n    showStorageFullDialog(); // offer export / server sync\n  } else {\n    throw e;\n  }\n}","preventionTips":["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."],"tags":["indexeddb","storage-quota","browser","data-loss"],"backgroundTag":"quota-exceeded","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}