{"record":{"id":"13d7cd516b324787","repo":"thedotmack/claude-mem","slug":"uninstall-could-not-remove-candidate","errorCode":null,"errorMessage":"[uninstall] Could not remove ${candidate}:","messagePattern":"\\[uninstall\\] Could not remove (.+?):","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/npx-cli/commands/uninstall.ts","lineNumber":191,"sourceCode":"  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);\n    } catch (error: unknown) {\n      console.warn(`[uninstall] Could not read ${cacheRoot}:`, error instanceof Error ? error.message : String(error));\n    }\n    for (const projectDir of projectDirs) {\n      const projectPath = join(cacheRoot, projectDir);\n      let logEntries: string[] = [];\n      try {\n        logEntries = readdirSync(projectPath);\n      } catch (error: unknown) {","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/e2d1df569a8f04075d40e92461128ece7cf04c82/src/npx-cli/commands/uninstall.ts#L173-L209","documentation":"While sweeping npx cache directories, uninstall runs rmSync(recursive, force) on each <hash>/node_modules/claude-mem copy. If the removal throws (EACCES/EPERM, or EBUSY on Windows because a node process still has files open), it warns and continues with the next candidate; that stray copy remains.","triggerScenarios":"`npx claude-mem uninstall` while a claude-mem worker or an npx-spawned process still runs from that cache directory; root-owned files inside _npx; Windows file locks from an indexer or antivirus.","commonSituations":"Uninstalling without stopping the worker first; leftover processes after a crashed run; sudo-created cache entries.","solutions":["Stop running claude-mem and node processes (ps aux | grep claude-mem, lsof +D <candidate>) and re-run uninstall","Fix ownership: sudo chown -R $(whoami) ~/.npm/_npx","Delete the path printed in the message manually: rm -rf <candidate>"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { accessSync, constants } from 'node:fs';\n// Before uninstall: the npx cache copy must be removable (not locked or read-only)\naccessSync(`${process.env.HOME}/.npm/_npx`, constants.R_OK | constants.W_OK); // throws EACCES/EPERM early","typeGuard":"function isErrnoException(error: unknown): error is NodeJS.ErrnoException {\n  return error instanceof Error && typeof (error as NodeJS.ErrnoException).code === 'string';\n}","tryCatchPattern":null,"preventionTips":["Stop the claude-mem worker and all node processes before uninstalling","Keep ~/.npm/_npx user-owned so rmSync does not hit EACCES","On Windows, close Claude sessions so file handles in the cache are released"],"tags":["uninstall","npx-cache","file-delete","process-lock"],"backgroundTag":"file-delete-permission-denied","analyzedSha":"e2d1df569a8f04075d40e92461128ece7cf04c82","analyzedAt":"2026-08-20T23:58:13.836Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}