{"record":{"id":"74ae86fa61ad33f0","repo":"thedotmack/claude-mem","slug":"uninstall-could-not-read-npxroot","errorCode":null,"errorMessage":"[uninstall] Could not read ${npxRoot}:","messagePattern":"\\[uninstall\\] Could not read (.+?):","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/npx-cli/commands/uninstall.ts","lineNumber":182,"sourceCode":"    }\n  }\n\n  if (dirty) {\n    writeJsonFileAtomic(claudeSettingsPath(), settings);\n  }\n}\n\nfunction removeStrayClaudeMemPaths(): number {\n  const home = homedir();\n  let removedCount = 0;\n\n  const npxRoot = join(home, '.npm', '_npx');\n  if (existsSync(npxRoot)) {\n    let hashDirs: string[] = [];\n    try {\n      hashDirs = readdirSync(npxRoot);\n    } catch (error: unknown) {\n      console.warn(`[uninstall] Could not read ${npxRoot}:`, error instanceof Error ? error.message : String(error));\n    }\n    for (const hashDir of hashDirs) {\n      const candidate = join(npxRoot, hashDir, 'node_modules', 'claude-mem');\n      if (!existsSync(candidate)) continue;\n      try {\n        rmSync(candidate, { recursive: true, force: true });\n        removedCount++;\n      } catch (error: unknown) {\n        console.warn(`[uninstall] Could not remove ${candidate}:`, error instanceof Error ? error.message : String(error));\n      }\n    }\n  }\n\n  const cacheRoot = join(home, '.cache', 'claude-cli-nodejs');\n  if (existsSync(cacheRoot)) {\n    let projectDirs: string[] = [];\n    try {\n      projectDirs = readdirSync(cacheRoot);","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/npx-cli/commands/uninstall.ts#L164-L200","documentation":"removeStrayClaudeMemPaths enumerates ~/.npm/_npx to locate leftover claude-mem copies inside npx hash directories. If readdirSync on the root throws (despite existsSync passing), the code logs this warning and continues with an empty hashDirs list, so no stray npx copies are removed. It is a non-fatal best-effort cleanup path.","triggerScenarios":"readdirSync(npxRoot) throws in the try block: permission denied on ~/.npm/_npx, the path disappeared between existsSync and readdirSync, or an I/O error on the directory.","commonSituations":"~/.npm owned by root after a sudo npm run; another concurrent npx process removing/renaming hash dirs; network filesystems with flaky I/O; SELinux/AppArmor policies restricting access to the npm cache.","solutions":["Fix permissions on ~/.npm/_npx (chown -R $(whoami) ~/.npm) and re-run uninstall.","Remove the directory manually if you have elevated rights: sudo rm -rf ~/.npm/_npx/<hash>/node_modules/claude-mem.","Re-run uninstall; the path may have been removed concurrently by another process.","Run npx clear-npx-cache (or delete ~/.npm/_npx) to clear the whole npx cache."],"exampleFix":"// before (uninstall runs as wrong user)\n$ sudo npx claude-mem uninstall\n// after\n$ npx claude-mem uninstall  # run as the user owning ~/.npm","handlingStrategy":"try-catch","validationCode":"import { accessSync, constants } from 'fs';\ntry { accessSync(npxRoot, constants.R_OK); } catch { console.warn(`Cannot read ${npxRoot}: fix permissions`); }","typeGuard":"function isReadError(e: unknown): e is NodeJS.ErrnoException {\n  return e instanceof Error && 'code' in e && ['EACCES','ENOENT','EIO'].includes((e as NodeJS.ErrnoException).code ?? '');\n}","tryCatchPattern":"try {\n  hashDirs = readdirSync(npxRoot);\n} catch (e) {\n  console.warn(`Cannot list ${npxRoot}: ${(e as NodeJS.ErrnoException).code ?? e}`);\n}","preventionTips":["Never run npm/npx commands with sudo; if you did, chown ~/.npm back to your user.","Avoid uninstalling while other npx sessions are running to prevent directory races.","Keep ~/.npm on a local (not network) filesystem when possible.","Clear the npx cache periodically (rm -rf ~/.npm/_npx) instead of surgical per-dir deletes."],"tags":["filesystem","permissions","npx","cleanup"],"backgroundTag":"file-read-failed","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}