{"record":{"id":"6299eb14a79cef04","repo":"thedotmack/claude-mem","slug":"npmpackagerootdirectory-expected-package-json-at","errorCode":null,"errorMessage":"npmPackageRootDirectory: expected package.json at ${root}. Bundle structure may have changed — update the path walk.","messagePattern":"npmPackageRootDirectory: expected package\\.json at (.+?)\\. Bundle structure may have changed — update the path walk\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/npx-cli/utils/paths.ts","lineNumber":44,"sourceCode":"}\n\nexport function installedPluginsPath(): string {\n  return join(pluginsDirectory(), 'installed_plugins.json');\n}\n\nexport function claudeSettingsPath(): string {\n  return join(claudeConfigDirectory(), 'settings.json');\n}\n\nexport function pluginCacheDirectory(version: string): string {\n  return join(pluginsDirectory(), 'cache', 'thedotmack', 'claude-mem', version);\n}\n\nexport function npmPackageRootDirectory(): string {\n  const currentFilePath = fileURLToPath(import.meta.url);\n  const root = join(dirname(currentFilePath), '..', '..');\n  if (!existsSync(join(root, 'package.json'))) {\n    throw new Error(\n      `npmPackageRootDirectory: expected package.json at ${root}. ` +\n      `Bundle structure may have changed — update the path walk.`,\n    );\n  }\n  return root;\n}\n\nexport function npmPackagePluginDirectory(): string {\n  return join(npmPackageRootDirectory(), 'plugin');\n}\n\nexport function readPluginVersion(): string {\n  const pluginJsonPath = join(npmPackagePluginDirectory(), '.claude-plugin', 'plugin.json');\n  if (existsSync(pluginJsonPath)) {\n    try {\n      const pluginJson = JSON.parse(readFileSync(pluginJsonPath, 'utf-8'));\n      if (pluginJson.version) return pluginJson.version;\n    } catch {","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/e2d1df569a8f04075d40e92461128ece7cf04c82/src/npx-cli/utils/paths.ts#L26-L62","documentation":"setThemePreference writes the chosen theme to localStorage; if setItem throws (QuotaExceededError in private browsing or full storage, SecurityError when storage is blocked) the message is console.warn'd but setPreference still runs — the theme applies in-memory for the session and simply won't survive a reload. Same storage-unavailability family as the read warning, but on the write path.","triggerScenarios":"Safari/Chrome private windows where setItem throws; storage quota exhausted by other keys; embedded context with storage blocked; browser settings forbidding site data.","commonSituations":"Incognito users toggling dark mode; iframe-embedded viewers with partitioned storage; devices with tiny storage quotas.","solutions":["No functional breakage — the theme applies for the session; only persistence is skipped.","Clear other localStorage keys on the origin if quota is genuinely exhausted.","Allow site data for the origin to restore persistence.","Detect repeated failures and switch to a cookie or in-memory-only mode deliberately."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"const setThemePreference = (newPreference: ThemePreference) => {\n  try {\n    localStorage.setItem(STORAGE_KEY, newPreference);\n  } catch (e: unknown) {\n    // Private mode / quota / blocked storage: apply in-memory anyway so UI still works\n    console.warn('Failed to save theme preference to localStorage:', e instanceof Error ? e.message : String(e));\n  }\n  setPreference(newPreference); // ALWAYS runs — persistence is optional, state change is not\n};","preventionTips":["Keep the state update outside the try block so a storage failure never blocks the UI change.","Detect QuotaExceededError by name and prune old keys before retrying once.","Test theming in a private window — it is the fastest way to catch storage-dependent UI bugs."],"tags":["ui","localstorage","quota-exceeded","theme","private-browsing"],"backgroundTag":"localstorage-quota-exceeded","analyzedSha":"e2d1df569a8f04075d40e92461128ece7cf04c82","analyzedAt":"2026-08-20T23:58:13.836Z","contentChangedAt":"2026-08-20T23:58:13.836Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}