{"record":{"id":"e3fa08c400623bcc","repo":"jlcodes99/cockpit-tools","slug":"accountstore-name-e3fa08","errorCode":null,"errorMessage":"[AccountStore] 删除持久化数据失败: ${name}","messagePattern":"\\[AccountStore\\] 删除持久化数据失败: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/stores/useAccountStore.ts","lineNumber":78,"sourceCode":"      if (isQuotaExceededError(error)) {\n        if (!accountStoreQuotaWarned) {\n          console.warn(\n            '[AccountStore] 本地缓存空间不足，已自动清理账号缓存并回退为仅内存态。',\n            error\n          );\n          accountStoreQuotaWarned = true;\n        }\n        scheduleAccountStoreQuotaRecovery(name);\n        return;\n      }\n      console.warn(`[AccountStore] 写入持久化数据失败: ${name}`, error);\n    }\n  },\n  removeItem: (name: string) => {\n    try {\n      localStorage.removeItem(name);\n    } catch (error) {\n      console.warn(`[AccountStore] 删除持久化数据失败: ${name}`, error);\n    }\n  },\n}));\n\nfunction toPersistedTokenSnapshot(token: TokenData): TokenData {\n  return {\n    access_token: '',\n    refresh_token: '',\n    expires_in: 0,\n    expiry_timestamp: 0,\n    token_type: token.token_type || 'Bearer',\n    email: token.email,\n    project_id: token.project_id,\n    is_gcp_tos: token.is_gcp_tos,\n    session_id: token.session_id,\n  };\n}\n","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/jlcodes99/cockpit-tools/blob/1ed8b77992d62ca81fabf744deb0839ad361d5bf/src/stores/useAccountStore.ts#L60-L96","documentation":"This warning is logged by the removeItem handler of a zustand persist storage shim when localStorage.removeItem(name) throws. The library wraps every storage call in try/catch because localStorage can fail (privacy mode, quota, disabled storage), and rather than crash state hydration/persistence it downgrades the failure to a console.warn. The persisted key named `name` could not be deleted, so stale data may remain in storage.","triggerScenarios":"Calling removeItem on the account store persist storage while localStorage.removeItem throws: storage disabled/blocked (Safari private mode, 'Block all cookies'), SecurityError from cross-origin iframe, quota exceeded during cleanup, or storage being cleared concurrently.","commonSituations":"Users with strict browser privacy settings; embedded WebView with localStorage disabled; corrupted storage entries that a framework tries to clean up during rehydrate/logout flows.","solutions":["Inspect the logged `error` object to identify the DOMException (SecurityError vs QuotaExceededError) and fix the environment cause","Verify the WebView/browser allows localStorage (cookies/site-data settings) for the app origin","Wrap the store's persist usage so storage failures degrade gracefully, or provide a custom storage fallback (e.g. in-memory) via the persist `storage` option","Clear site data manually and retry the account removal flow"],"exampleFix":"// before\nremoveItem: (name) => {\n  localStorage.removeItem(name);\n}\n// after\nremoveItem: (name) => {\n  try {\n    localStorage.removeItem(name);\n  } catch (error) {\n    console.warn(`[AccountStore] 删除持久化数据失败: ${name}`, error);\n  }\n}","handlingStrategy":"try-catch","validationCode":"function isLocalStorageAvailable() {\n  try {\n    const k = '__test__';\n    window.localStorage.setItem(k, '1');\n    window.localStorage.removeItem(k);\n    return true;\n  } catch {\n    return false;\n  }\n}","typeGuard":"function hasLocalStorage(win: Window): win is Window & { localStorage: Storage } {\n  try {\n    return typeof win.localStorage !== 'undefined';\n  } catch {\n    return false;\n  }\n}","tryCatchPattern":"try {\n  localStorage.removeItem(name);\n} catch (error) {\n  console.warn(`[AccountStore] 删除持久化数据失败: ${name}`, error);\n  fallbackInMemoryStore.remove(name); // degrade gracefully\n}","preventionTips":["Feature-detect localStorage availability before wiring the persist storage","Provide a createJSONStorage fallback (memory storage) for private-mode browsers","Log the DOMException name to distinguish SecurityError from QuotaExceededError","Test account removal in privacy mode and with storage disabled"],"tags":["localstorage","tauri-webview","persistence"],"backgroundTag":"localstorage-access-denied","analyzedSha":"1ed8b77992d62ca81fabf744deb0839ad361d5bf","analyzedAt":"2026-09-05T09:51:41.178Z","contentChangedAt":"2026-09-05T09:51:41.178Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}