koala73/worldmonitor · error
Settings export could not read browser storage.
Error message
Settings export could not read browser storage.
What it means
exportSettings builds a settings backup from a snapshot of the browser's storage (localStorage etc.) taken by safeStorageSnapshot(). If any underlying storage read throws — the snapshot reports ok=false rather than degrading to an empty backup — exportSettings throws so it never ships a backup that silently looks successful but is empty.
Solutions
- Detect storage availability up front (try a test localStorage read) and show the user an explanatory message with browser-settings guidance before exporting.
- Catch this error in the UI and offer an alternative export path (e.g. export current in-memory settings state instead of storage-backed values).
- If running in an iframe, ensure the document has storage access (requestStorageAccess / proper permissions policy) or export from a top-level context.
- Retry the export once after the user adjusts browser settings and storage becomes readable.
Example fix
// before
const backup = exportSettings(); // throws when storage is blocked
// after
let backup;
try {
backup = exportSettings();
} catch (err) {
if (err instanceof Error && err.message.includes('could not read browser storage')) {
notifyUser('Browser storage is blocked; enable site data or export current settings instead.');
backup = buildBackupFromInMemoryState();
} else throw err;
} Defensive patterns
Strategy: try-catch
Validate before calling
function storageIsReadable(): boolean {
try {
const k = '__wm_probe__';
window.localStorage.setItem(k, '1');
window.localStorage.removeItem(k);
return true;
} catch {
return false;
}
}
if (!storageIsReadable()) warnUserBeforeExport(); Try / catch
try {
const backup = exportSettings();
} catch (err) {
if (err instanceof Error && err.message === 'Settings export could not read browser storage.') {
showStorageBlockedDialog(); // guide user to enable site data, or export in-memory state
} else throw err;
} Prevention
- Probe storage availability at app boot and disable export/import buttons with an explanation when blocked.
- Handle Safari/Brave privacy modes and third-party iframe storage partitioning explicitly.
- Offer an in-memory fallback backup so users can still leave with their settings when storage is denied.
When it happens
Trigger: Calling exportSettings when browser storage is unreadable: localStorage access blocked (browser privacy mode / 'Block all cookies'), StorageDisabled SecurityError in sandboxed iframes, quota/state errors, or storage poisoned by an extension that throws on property access.
Common situations: Users on strict privacy settings or Brave/Safari locking down storage; the app embedded in a third-party iframe with partitioned storage; automated headless browsers denying storage; corporate policies disabling site data.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-09-15).
Data as JSON: /api/errors/ba7b29c6143a4ba2.
Report an issue: GitHub.
Appendix: source
Thrown at src/utils/settings-persistence.ts:62
export function exportSettings(): void {
const data: Record<string, string> = {};
// Storage that cannot be read has no settings to export, and handing the
// user a downloadable file anyway is worse than failing: the caller in
// preferences-content.ts wraps this in try/catch and shows `exportSuccess`
// when it returns, so a silent empty payload becomes a green "Exported"
// toast over a backup containing nothing (#7833 review). Stay loud.
//
// Testing AVAILABILITY is not enough on its own, which an earlier round of
// this fix got wrong: a handle can exist while enumeration or an individual
// read throws, and the degrading accessors then return `[]`/`null` and
// rebuild exactly that empty-but-successful backup. The snapshot reports
// whether the reads themselves succeeded, so a partial one fails instead of
// shipping a backup the user would only discover was empty when restoring.
const snapshot = safeStorageSnapshot();
if (!snapshot.ok) {
throw new Error('Settings export could not read browser storage.');
}
let variant = 'full';
for (const [key, value] of snapshot.entries) {
if (key === 'worldmonitor-variant' && value) variant = value;
if (isSettingsKey(key)) data[key] = value;
}
const exportData: ExportedSettings = {
version: 1,
timestamp: new Date().toISOString(),
variant,
data,
};
const blob = new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');View on GitHub (pinned to 7d06c8633d)