koala73/worldmonitor · error
Telegram watchlist could not be saved
Error message
Telegram watchlist could not be saved
What it means
setTelegramWatchlistEntries serializes the normalized entry list and writes it to localStorage under STORAGE_KEY; any storage failure (quota exceeded, private-browsing restrictions, storage disabled or evicted) is caught and rethrown as 'Telegram watchlist could not be saved'. Persistence failed, so the in-memory dispatch is skipped and the caller knows the list was not saved.
Source
Thrown at src/services/telegram-watchlist.ts:89
export function getTelegramWatchlistEntries(): TelegramWatchlistEntry[] {
try {
const parsed = safeParseJson<unknown>(localStorage.getItem(STORAGE_KEY));
if (!Array.isArray(parsed)) return [];
return normalizeEntries(parsed);
} catch {
return [];
}
}
export function setTelegramWatchlistEntries(entries: TelegramWatchlistEntry[]): TelegramWatchlistEntry[] {
const next = normalizeEntries(entries || []);
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(next));
} catch {
throw new Error('Telegram watchlist could not be saved');
}
dispatch(next);
return next;
}
export function addTelegramWatchlistEntry(entry: TelegramWatchlistEntry): TelegramWatchlistEntry[] {
const normalized = coerceEntry(entry);
if (!normalized) return getTelegramWatchlistEntries();
const current = getTelegramWatchlistEntries();
const existing = current.findIndex(item => item.username === normalized.username);
if (existing >= 0) {
const existingEntry = current[existing];
if (!existingEntry) return current;
current[existing] = normalized.title
? { username: existingEntry.username, title: normalized.title }
: existingEntry;View on GitHub (pinned to 9361220cc0)
Solutions
- Wrap watchlist writes in try/catch and keep an in-memory list so the UI still works for the session when persistence fails.
- Check storage availability up front (probe localStorage with a test write) and switch to a memory-only mode with a 'not persisted' notice.
- Free quota by pruning other localStorage keys or trimming watchlist entries (e.g. drop unused preview caches) before retrying.
- Offer an export/import (JSON download) fallback so users on restricted browsers don't lose their watchlist.
Example fix
// before
addTelegramWatchlistEntry(entry); // throws when storage is blocked
// after
try {
addTelegramWatchlistEntry(entry);
} catch {
memoryWatchlist.push(entry);
showToast('Watchlist saved for this session only (storage unavailable)');
} Defensive patterns
Strategy: try-catch
Validate before calling
function storageAvailable(): boolean {
try {
const k = '__wm_probe__';
localStorage.setItem(k, '1');
localStorage.removeItem(k);
return true;
} catch {
return false;
}
}
Try / catch
try {
setTelegramWatchlistEntries(next);
} catch {
memoryWatchlist = next; // session-only fallback
showToast('Storage unavailable — watchlist kept for this session only');
}
Prevention
- Probe localStorage availability at boot and switch to memory-only mode when blocked
- Keep an in-memory mirror of the watchlist so UI actions survive storage failures
- Watch for QuotaExceededError and prune stale keys before giving up
- Offer JSON export/import so users on restricted browsers can preserve their watchlist
When it happens
Trigger: Calling setTelegramWatchlistEntries (directly or via addTelegramWatchlistEntry/removeTelegramWatchlistEntry) when localStorage.setItem throws: quota exceeded (QuotaExceededError), Safari private mode, storage disabled by browser policy, or a page origin with storage partitioned away.
Common situations: Users in private/incognito browsing with storage blocked; localStorage full from other app data; embedded webviews or strict privacy settings disabling storage; corporate browsers with site-data restrictions.
Related errors
- TICKERS_LIMIT_EXCEEDED
- Failed to persist resilience trace generation for ${generati
- Failed to persist resilience score generation for ${generati
AI-assisted analysis of koala73/worldmonitor@9361220cc0 (2026-09-01).
Data as JSON: /api/errors/050d396f7f8e7e54.
Report an issue: GitHub.