thedotmack/claude-mem · warning

[uninstall] Could not read

Error message

[uninstall] Could not read ${npxRoot}:

What it means

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.

Solutions

  1. Fix permissions on ~/.npm/_npx (chown -R $(whoami) ~/.npm) and re-run uninstall.
  2. Remove the directory manually if you have elevated rights: sudo rm -rf ~/.npm/_npx/<hash>/node_modules/claude-mem.
  3. Re-run uninstall; the path may have been removed concurrently by another process.
  4. Run npx clear-npx-cache (or delete ~/.npm/_npx) to clear the whole npx cache.

Example fix

// before (uninstall runs as wrong user)
$ sudo npx claude-mem uninstall
// after
$ npx claude-mem uninstall  # run as the user owning ~/.npm
Defensive patterns

Strategy: try-catch

Validate before calling

import { accessSync, constants } from 'fs';
try { accessSync(npxRoot, constants.R_OK); } catch { console.warn(`Cannot read ${npxRoot}: fix permissions`); }

Type guard

function isReadError(e: unknown): e is NodeJS.ErrnoException {
  return e instanceof Error && 'code' in e && ['EACCES','ENOENT','EIO'].includes((e as NodeJS.ErrnoException).code ?? '');
}

Try / catch

try {
  hashDirs = readdirSync(npxRoot);
} catch (e) {
  console.warn(`Cannot list ${npxRoot}: ${(e as NodeJS.ErrnoException).code ?? e}`);
}

Prevention

When it happens

Trigger: 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.

Common situations: ~/.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.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17). Data as JSON: /api/errors/74ae86fa61ad33f0. Report an issue: GitHub.

Appendix: source

Thrown at src/npx-cli/commands/uninstall.ts:182

    }
  }

  if (dirty) {
    writeJsonFileAtomic(claudeSettingsPath(), settings);
  }
}

function removeStrayClaudeMemPaths(): number {
  const home = homedir();
  let removedCount = 0;

  const npxRoot = join(home, '.npm', '_npx');
  if (existsSync(npxRoot)) {
    let hashDirs: string[] = [];
    try {
      hashDirs = readdirSync(npxRoot);
    } catch (error: unknown) {
      console.warn(`[uninstall] Could not read ${npxRoot}:`, error instanceof Error ? error.message : String(error));
    }
    for (const hashDir of hashDirs) {
      const candidate = join(npxRoot, hashDir, 'node_modules', 'claude-mem');
      if (!existsSync(candidate)) continue;
      try {
        rmSync(candidate, { recursive: true, force: true });
        removedCount++;
      } catch (error: unknown) {
        console.warn(`[uninstall] Could not remove ${candidate}:`, error instanceof Error ? error.message : String(error));
      }
    }
  }

  const cacheRoot = join(home, '.cache', 'claude-cli-nodejs');
  if (existsSync(cacheRoot)) {
    let projectDirs: string[] = [];
    try {
      projectDirs = readdirSync(cacheRoot);

View on GitHub (pinned to d8bc9755e7)