paperclipai/paperclip · error · Error

Refusing to remove install store without a manifest at

Error message

Refusing to remove install store without a manifest at ${paths.cliRoot}.

What it means

The install store passed marker verification but has no install.json manifest, so payloads cannot be accounted for and removal is refused.

Solutions

  1. Ensure the install store has a manifest before removal; if not, remove the directory manually after verifying it is safe.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at cli/src/install-store.ts:139 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-08-18). Data as JSON: /api/errors/78dfaf03ff24f4c3. Report an issue: GitHub.

Appendix: source

Thrown at cli/src/install-store.ts:139

  assertOwnedByCurrentUser(cliStat, paths.cliRoot);
  let markerStat: fs.Stats;
  try {
    markerStat = fs.lstatSync(paths.markerPath);
  } catch (error) {
    if ((error as NodeJS.ErrnoException).code === "ENOENT") {
      throw new Error(`Refusing to remove unverified install store ${paths.cliRoot}.`);
    }
    throw error;
  }
  if (!markerStat.isFile() || markerStat.isSymbolicLink() || markerStat.nlink > 1) {
    throw new Error(`Refusing to remove unverified install store ${paths.cliRoot}.`);
  }
  assertOwnedByCurrentUser(markerStat, paths.markerPath);
  if (fs.readFileSync(paths.markerPath, "utf8") !== MANAGED_STORE_MARKER) {
    throw new Error(`Refusing to remove unverified install store ${paths.cliRoot}.`);
  }
  const manifest = readInstallManifest(paths);
  if (!manifest) throw new Error(`Refusing to remove install store without a manifest at ${paths.cliRoot}.`);
  const relativePayload = path.relative(paths.installsRoot, path.resolve(manifest.payloadPath));
  if (!relativePayload || relativePayload.startsWith("..") || path.isAbsolute(relativePayload)) {
    throw new Error(`Refusing to remove install store with an invalid manifest at ${paths.cliRoot}.`);
  }
  return manifest;
}

export async function withInstallStoreLock<T>(
  callback: () => Promise<T>,
  paths = resolveInstallStorePaths(),
  options: { initialize?: boolean } = {},
): Promise<T> {
  if (options.initialize !== false) initializeInstallStore(paths);
  const token = `${process.pid}:${Date.now()}:${Math.random().toString(16).slice(2)}`;
  const processIsAlive = (pid: number): boolean => {
    try {
      process.kill(pid, 0);
      return true;

View on GitHub (pinned to 01ad858492)