paperclipai/paperclip · warning · Error
Another managed install is already running${ownerLabel}. If
Error message
Another managed install is already running${ownerLabel}. If no install process is active, remove the stale lock at ${paths.lockPath} and retry. What it means
Thrown by withInstallStoreLock() when the install lock file (.install.lock) is held and the owning PID is still alive (process.kill(pid,0) succeeds or returns EPERM, meaning the process exists). The library auto-recovers stale locks (dead owner) but refuses to steal a lock from a live process. The message includes the owner PID when parseable and tells the user exactly which lock file to remove if they are sure no install is running.
Source
Thrown at cli/src/install-store.ts:181
const temporaryPath = `${paths.lockPath}.${token}.tmp`;
try {
fs.writeFileSync(temporaryPath, `${token}\n`, { mode: 0o600, flag: "wx" });
try {
fs.linkSync(temporaryPath, paths.lockPath);
return;
} catch (error) {
if ((error as NodeJS.ErrnoException).code !== "EEXIST") throw error;
}
const owner = fs.readFileSync(paths.lockPath, "utf8").trim();
const ownerPid = Number.parseInt(owner.split(":", 1)[0] ?? "", 10);
if (Number.isInteger(ownerPid) && ownerPid > 0 && !processIsAlive(ownerPid)) {
fs.rmSync(paths.lockPath);
fs.rmSync(temporaryPath, { force: true });
acquire();
return;
}
const ownerLabel = Number.isInteger(ownerPid) && ownerPid > 0 ? ` (pid ${ownerPid})` : "";
throw new Error(
`Another managed install is already running${ownerLabel}. ` +
`If no install process is active, remove the stale lock at ${paths.lockPath} and retry.`,
);
} finally {
fs.rmSync(temporaryPath, { force: true });
}
};
acquire();
try {
return await callback();
} finally {
try {
if (fs.readFileSync(paths.lockPath, "utf8").trim() === token) {
fs.rmSync(paths.lockPath, { force: true });
}
} catch (error) {
if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;View on GitHub (pinned to 67001ec6eb)
Solutions
- Wait for the other install (pid shown in the message) to finish, then retry.
- Confirm via 'ps -p <pid>' whether the owner is genuinely an install process; if it is hung, kill it ('kill <pid>').
- If no install is actually running (lock is stale but PID was reused by an unrelated live process), remove the lock file at the path shown and retry.
- Serialize install invocations with a higher-level lock or queue to avoid concurrent runs.
Example fix
$ paperclipai install Error: Another managed install is already running (pid 12345)... $ ps -p 12345 # confirm if real install $ kill 12345 # if hung $ rm ~/.paperclip/cli/.install.lock $ paperclipai install
Defensive patterns
Strategy: retry
Validate before calling
import fs from "node:fs";
import { resolveInstallStorePaths } from "./install-store.js";
function isLockHeldByLiveProcess(paths = resolveInstallStorePaths()): boolean {
try {
const owner = fs.readFileSync(paths.lockPath, "utf8").trim();
const pid = Number.parseInt(owner.split(":", 1)[0] ?? "", 10);
if (!Number.isInteger(pid) || pid <= 0) return true; // unknown owner → treat as held
try { process.kill(pid, 0); return true; }
catch (e) { return (e as NodeJS.ErrnoException).code === "EPERM"; }
} catch { return false; }
} Try / catch
try {
return await withInstallStoreLock(doInstall, paths);
} catch (err) {
if (err instanceof Error && err.message.startsWith("Another managed install is already running")) {
// Option A: wait and retry. Option B: surface to user with the PID + lock path.
console.error(err.message);
process.exit(1);
}
throw err;
} Prevention
- Serialize install commands — do not run two 'paperclipai install' concurrently.
- In CI, ensure the previous install step fully exited before starting the next.
- If an install hangs, kill the owning PID before removing the lock file manually.
- Do not delete .install.lock while a real install is running.
When it happens
Trigger: Called withInstallStoreLock() while another process holds the lock: linkSync(temporaryPath, lockPath) returned EEXIST, the owner PID read from the lock is a positive integer, and processIsAlive(ownerPid) returned true (process exists).
Common situations: 1) Two concurrent 'paperclipai install' invocations. 2) A previous install is still running in another terminal or CI step. 3) A long-running install hung without exiting. 4) A background scheduler kicked off a second install before the first finished.
Related errors
- Another restart for instance ${instanceId} is still running.
- Worktree seed lock ${lockPath} belongs to exited process ${c
- Worktree seed lock ${lockPath} is stale or malformed. Verify
- Refusing to use non-directory install-store path ${directory
- Refusing to modify path not owned by the current user: ${tar
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/c75098839732beb1.
Report an issue: GitHub.