lablup / lablup/backend.ai-webui
Chat history localStorage cache overflows when image attachments are stored as base64 data URLs
- Dominant language
- TypeScript
- Stars
- 133
- Forks
- 81
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 355
Description
## Summary
Follow-up to FR-3161. The chat attachment fix encodes uploaded images as base64 `data:` URLs embedded in `message.parts`. Chat history is persisted to `localStorage`, so every stored message now carries the full base64 image. A single photo is often several MB, which quickly exceeds the browser's ~5 MB per-origin `localStorage` quota.
## Root cause
`react/src/components/Chat/ChatHistory.ts` persists the whole chat-history map to `localStorage` on every message save:
- `createLocalStorageCache.set()` / `delete()` call `localStorage.setItem('backendaiwebui.cache.chat_history', JSON.stringify(Array.from(cache.entries())))` (lines 46, 60).
- `saveChatMessage` (wired through `onSaveMessage` in `ChatCard.tsx`) stores `message.parts`, which after FR-3161 include base64 `data:` image URLs.
Two problems:
1. `localStorage.setItem` has no try/catch, so once the serialized history exceeds the quota it throws `QuotaExceededError` uncaught, breaking chat-history persistence and the save flow.
1. Even below quota, the entire history map is re-serialized on every save, so large base64 blobs degrade performance as history grows.
## Steps to reproduce
1. Open the Chat page.
1. Attach a few images (a few MB each) across messages.
1. Continue chatting; the serialized history grows with each base64 blob.
1. Once the cache exceeds ~5 MB, `localStorage.setItem` throws `QuotaExceededError` and history persistence fails.
## Expected
Chat history persistence does not break when image attachments are present; large attachment bytes are not naively stored in `localStorage`.
## Possible directions
- Do not persist raw attachment bytes in `localStorage`: strip/replace `data:` URL parts with a lightweight placeholder or metadata before caching.
- Or move attachment-bearing chat history to IndexedDB (much larger quota).
- Or guard `setItem` with try/catch plus quota-aware eviction and a user-facing warning.
## Related
Introduced by the FR-3161 data-URL attachment fix (PR #7946).
JIRA Issue: FR-3167
Contributor guide
No contributing guide indexed for this repository
Research direction
Read react/src/components/Chat/ChatHistory.ts, focusing on createLocalStorageCache.set() and delete(), then trace saveChatMessage through onSaveMessage in ChatCard.tsx. Review FR-3161 and PR #7946 for the attachment behavior. Done means chat history with image attachments no longer breaks localStorage persistence or stores large raw attachment data there.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100