rohitg00/agentmemory · error

EPERM

EPERM

Error message

No permission to signal pid ${pid}. Try: kill ${pid}

What it means

Warning from the stop/kill routine when process.kill(pid, signal) fails with EPERM — the OS refused to signal the target process because the current user lacks permission. The engine is NOT stopped by this attempt.

Solutions

  1. Run the same kill command with sudo: `sudo kill <pid>`
  2. Stop the process as the user who started it (log in as that user and stop the engine)
  3. If it is a stale foreign pidfile, remove ~/.agentmemory/iii.pid after confirming the process is not yours

Example fix

// before
$ agentmemory stop
warn: No permission to signal pid 4321. Try: kill 4321
// after
$ sudo kill 4321
Defensive patterns

Strategy: try-catch

Validate before calling

const os = require("os");
function canSignal(pid) { try { process.kill(pid, 0); return true; } catch (e) { return e.code === "EPERM" ? "eprem" : false; } }

Type guard

function isEperm(e: unknown): e is NodeJS.ErrnoException { return (e as NodeJS.ErrnoException)?.code === "EPERM"; }

Try / catch

try { process.kill(pid, signal); } catch (err) {
  if ((err as NodeJS.ErrnoException)?.code === "EPERM") {
    console.warn(`Permission denied for pid ${pid}; retry with sudo kill ${pid}`);
  }
}

Prevention

When it happens

Trigger: Calling the stop command where the recorded/listed pid belongs to a process owned by another user (e.g. a daemon started by root or another account).

Common situations: Engine previously started with sudo, mixed-user installs, containers where the pid is owned by a different uid, shared dev servers.

Related errors


AI-assisted analysis of rohitg00/agentmemory@e04ba88819 (2026-08-30). Data as JSON: /api/errors/aae7e437867a33e4. Report an issue: GitHub.

Appendix: source

Thrown at src/cli.ts:3265

    }
    return true;
  } catch (err) {
    return (err as NodeJS.ErrnoException)?.code === "EPERM";
  }
}

async function signalAndWait(
  pid: number,
  initialSignal: NodeJS.Signals,
  timeoutMs: number,
): Promise<boolean> {
  try {
    process.kill(pid, initialSignal);
  } catch (err) {
    const code = (err as NodeJS.ErrnoException)?.code;
    if (code === "ESRCH") return true;
    if (code === "EPERM") {
      p.log.warn(`No permission to signal pid ${pid}. Try: kill ${pid}`);
      return false;
    }
    vlog(`${initialSignal} ${pid}: ${err instanceof Error ? err.message : String(err)}`);
    return false;
  }
  const deadline = Date.now() + timeoutMs;
  while (Date.now() < deadline) {
    if (!pidAlive(pid)) return true;
    await new Promise((r) => setTimeout(r, 200));
  }
  if (!pidAlive(pid)) return true;
  try {
    process.kill(pid, "SIGKILL");
  } catch (err) {
    if ((err as NodeJS.ErrnoException)?.code === "ESRCH") return true;
    vlog(`SIGKILL ${pid}: ${err instanceof Error ? err.message : String(err)}`);
    return false;
  }

View on GitHub (pinned to e04ba88819)