thedotmack/claude-mem · warning

[uninstall] Could not remove

Error message

[uninstall] Could not remove ${pluginDataDir}:

What it means

removeStrayClaudeMemPaths removes the plugin data directory ~/.claude/plugins/data/claude-mem-thedotmack with rmSync(recursive, force). If the deletion throws, this warning is logged and the directory is left intact; the function still returns whatever removedCount it accumulated. Uninstall completes without failing.

Solutions

  1. Ensure the claude-mem worker is stopped (re-run uninstall; it stops the worker first), then delete manually: rm -rf ~/.claude/plugins/data/claude-mem-thedotmack.
  2. Fix ownership: sudo chown -R $(whoami) ~/.claude/plugins/data, then re-run uninstall.
  3. Remove with elevation if needed: sudo rm -rf ~/.claude/plugins/data/claude-mem-thedotmack.
  4. Check ACLs (ls -le on macOS / getfacl on Linux) if ownership looks correct but writes still fail.

Example fix

// before (worker still running, db file locked)
rmSync(pluginDataDir, { recursive: true, force: true }); // EBUSY
// after (stop worker first)
// npx claude-mem worker stop
rmSync(pluginDataDir, { recursive: true, force: true });
Defensive patterns

Strategy: try-catch

Validate before calling

import { accessSync, constants } from 'fs';
try { accessSync(pluginDataDir, constants.W_OK); } catch { console.warn(`Cannot delete ${pluginDataDir} — check ownership and ACLs`); }

Type guard

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

Try / catch

try {
  rmSync(pluginDataDir, { recursive: true, force: true });
} catch (e) {
  const code = (e as NodeJS.ErrnoException).code;
  console.warn(`Plugin data not removed (${code}) — stop the worker and delete ${pluginDataDir} manually`);
}

Prevention

When it happens

Trigger: rmSync(pluginDataDir, { recursive: true, force: true }) throws — EACCES/EPERM (directory owned by root or another user), EBUSY (files in use by the plugin worker), or ENOSPC/IO errors on exotic filesystems.

Common situations: Plugin data written by a sudo-run Claude session; the claude-mem worker still running and holding database files open in that directory; managed workstations with ACLs on ~/.claude.

Related errors


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

Appendix: source

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

        if (!entry.startsWith('mcp-logs-plugin-claude-mem-')) continue;
        const logPath = join(projectPath, entry);
        try {
          rmSync(logPath, { recursive: true, force: true });
          removedCount++;
        } catch (error: unknown) {
          console.warn(`[uninstall] Could not remove ${logPath}:`, error instanceof Error ? error.message : String(error));
        }
      }
    }
  }

  const pluginDataDir = join(home, '.claude', 'plugins', 'data', 'claude-mem-thedotmack');
  if (existsSync(pluginDataDir)) {
    try {
      rmSync(pluginDataDir, { recursive: true, force: true });
      removedCount++;
    } catch (error: unknown) {
      console.warn(`[uninstall] Could not remove ${pluginDataDir}:`, error instanceof Error ? error.message : String(error));
    }
  }

  return removedCount;
}

export async function runUninstallCommand(): Promise<void> {
  p.intro(styleText(['bgRed', 'white'], ' claude-mem uninstall '));

  if (!isPluginInstalled()) {
    p.log.warn('claude-mem does not appear to be installed.');

    if (process.stdin.isTTY) {
      const shouldCleanup = await p.confirm({
        message: 'Clean up any remaining registration data anyway?',
        initialValue: false,
      });

View on GitHub (pinned to d8bc9755e7)