{"record":{"id":"78dfaf03ff24f4c3","repo":"paperclipai/paperclip","slug":"refusing-to-remove-install-store-without-a-manifes","errorCode":null,"errorMessage":"Refusing to remove install store without a manifest at ${paths.cliRoot}.","messagePattern":"Refusing to remove install store without a manifest at (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"cli/src/install-store.ts","lineNumber":139,"sourceCode":"  assertOwnedByCurrentUser(cliStat, paths.cliRoot);\n  let markerStat: fs.Stats;\n  try {\n    markerStat = fs.lstatSync(paths.markerPath);\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n      throw new Error(`Refusing to remove unverified install store ${paths.cliRoot}.`);\n    }\n    throw error;\n  }\n  if (!markerStat.isFile() || markerStat.isSymbolicLink() || markerStat.nlink > 1) {\n    throw new Error(`Refusing to remove unverified install store ${paths.cliRoot}.`);\n  }\n  assertOwnedByCurrentUser(markerStat, paths.markerPath);\n  if (fs.readFileSync(paths.markerPath, \"utf8\") !== MANAGED_STORE_MARKER) {\n    throw new Error(`Refusing to remove unverified install store ${paths.cliRoot}.`);\n  }\n  const manifest = readInstallManifest(paths);\n  if (!manifest) throw new Error(`Refusing to remove install store without a manifest at ${paths.cliRoot}.`);\n  const relativePayload = path.relative(paths.installsRoot, path.resolve(manifest.payloadPath));\n  if (!relativePayload || relativePayload.startsWith(\"..\") || path.isAbsolute(relativePayload)) {\n    throw new Error(`Refusing to remove install store with an invalid manifest at ${paths.cliRoot}.`);\n  }\n  return manifest;\n}\n\nexport async function withInstallStoreLock<T>(\n  callback: () => Promise<T>,\n  paths = resolveInstallStorePaths(),\n  options: { initialize?: boolean } = {},\n): Promise<T> {\n  if (options.initialize !== false) initializeInstallStore(paths);\n  const token = `${process.pid}:${Date.now()}:${Math.random().toString(16).slice(2)}`;\n  const processIsAlive = (pid: number): boolean => {\n    try {\n      process.kill(pid, 0);\n      return true;","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/install-store.ts#L121-L157","documentation":"Thrown by assertManagedInstallStore() after the marker is verified but readInstallManifest(paths) returns null — meaning the install.json manifest file is absent (ENOENT). The library refuses to remove a store whose manifest is missing because it cannot determine the payload path to safely prune, and removing blindly could leave orphaned or destroy wanted data.","triggerScenarios":"Called assertManagedInstallStore() where the marker is valid but paths.manifestPath (~/.paperclip/cli/install.json) does not exist, so readInstallManifest returns null.","commonSituations":"1) Partial uninstall removed install.json but left the rest of the store. 2) The store was initialized but no install ever completed to write a manifest. 3) The manifest was manually deleted. 4) A sync excluded install.json.","solutions":["If the store is stale, remove cliRoot manually ('rm -rf ~/.paperclip/cli') and reinitialize with 'paperclipai install'.","If a known-good manifest exists in a backup, restore install.json to paths.manifestPath and retry.","Run 'paperclipai install' to perform a fresh install which will write a new manifest.","Do not fabricate a manifest by hand — its payloadPath must point at a real payload under installsRoot."],"exampleFix":"$ ls ~/.paperclip/cli/install.json\nls: install.json: No such file or directory\n$ rm -rf ~/.paperclip/cli\n$ paperclipai install","handlingStrategy":"validation","validationCode":"import fs from \"node:fs\";\nimport { resolveInstallStorePaths } from \"./install-store.js\";\n\nfunction manifestExists(paths = resolveInstallStorePaths()): boolean {\n  return fs.existsSync(paths.manifestPath);\n}","typeGuard":"import { readInstallManifest, resolveInstallStorePaths } from \"./install-store.js\";\n\nfunction hasManifest(paths = resolveInstallStorePaths()): boolean {\n  return readInstallManifest(paths) !== null;\n}","tryCatchPattern":"try {\n  assertManagedInstallStore(paths);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"without a manifest\")) {\n    console.error(\"Manifest missing. Reset: rm -rf ~/.paperclip/cli && paperclipai install\");\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["Never delete install.json without removing the whole store.","Run 'paperclipai install' to (re)write a manifest after any partial cleanup.","Include install.json in backups of the store."],"tags":["install-store","manifest","removal-safety","cli"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}