Skip to content

fix: prevent localStorage quota overflow in plugin safety cache#1326

Open
OnlookerRs wants to merge 1 commit intokwaroran:mainfrom
OnlookerRs:fix/safety-cache-localstorage-quota
Open

fix: prevent localStorage quota overflow in plugin safety cache#1326
OnlookerRs wants to merge 1 commit intokwaroran:mainfrom
OnlookerRs:fix/safety-cache-localstorage-quota

Conversation

@OnlookerRs
Copy link
Copy Markdown
Contributor

PR Checklist

  • Required Checks
    • Have you added type definitions?
    • Have you tested your changes?
    • Have you checked that it won't break any existing features?
  • If your PR uses models1, check the following:
    • Have you checked if it works normally in all models?
    • Have you checked if it works normally in all web, local, and node-hosted versions? If it doesn't, have you blocked it in those versions?
  • If your PR is highly AI generated2, check the following:
    • Have you understood what the code does?
    • Have you cleaned up any unnecessary or redundant code?
    • Is it not a huge change?

Summary

checkCodeSafety in pluginSafety.ts stores the full modifiedCode in localStorage for each plugin, keyed by code hash (safety-${hash}). When plugins are updated, old entries are never removed and new ones accumulate indefinitely. Once localStorage quota is exceeded, the unhandled QuotaExceededError from localStorage.setItem crashes checkCodeSafety, which in turn crashes loadV2Plugin, preventing all plugins (including V3) from loading.

This affects all platforms, environments with smaller quotas (e.g. Safari iOS at 5 MB) hit it sooner, but any environment will eventually reach the limit given enough plugin updates.

Related Issues

None

Changes

  • Wrapped cache read (localStorage.getItem + JSON.parse) in try-catch; removes stale entry on checkerVersion mismatch or parse failure
  • Wrapped cache write (localStorage.setItem) in try-catch; on quota error, purges all safety-* entries and retries once
  • Added purgeSafetyCache helper that removes all safety-* localStorage entries except an optional keep key

Impact

  • Fixes all-plugins-dead scenario caused by localStorage quota overflow
  • No behavioral change in normal operation, try-catch only activates on error
  • Worst case after purge: one-time AST re-parse per plugin on next load (cache rebuilds itself)
  • Only safety-* keys are touched; no other localStorage data is affected

Additional Notes

The safety-* cache entries can be large (hundreds of KB each for big plugins) because they store the entire transformed source code. A single large plugin updated a few times can consume over 1 MB of orphaned cache entries. This fix is reactive (purge on quota error) rather than proactive, keeping the change minimal and preserving the existing caching strategy.

Footnotes

  1. Modifies the behavior of prompting, requesting, or handling responses from AI models.

  2. Over 80% of the code is AI generated.

Copy link
Copy Markdown
Collaborator

@cubicj cubicj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified. The try-catch + purge-and-retry correctly downgrades the crash into a one-time cache rebuild, and the read path also cleans stale entries. safety- prefix is only used here, so purge is safe.

One thing left open: orphan entries from old plugin versions still accumulate until the quota is hit. This fix reacts when that happens, but doesn't prevent the buildup itself. Worth considering as a follow-up, but out of scope here.

Approving — thanks for the contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants