lablup / lablup/backend.ai-webui

Chat history localStorage cache overflows when image attachments are stored as base64 data URLs

Open
#7,959 0 comments 0 reactions 0 assignees View on GitHub
frontend
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.