{"record":{"id":"0ad5697ce751239e","repo":"paperclipai/paperclip","slug":"refusing-to-prune-unsafe-install-store-path-sour","errorCode":null,"errorMessage":"Refusing to prune unsafe install-store path ${sourceRoot}.","messagePattern":"Refusing to prune unsafe install-store path (.+?)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/src/install-store.ts","lineNumber":337,"sourceCode":"    .slice(0, 2);\n\n  return { schemaVersion: INSTALL_MANIFEST_VERSION, ...record, previous };\n}\n\nexport function pruneInstallPayloads(\n  manifest: InstallManifest,\n  paths = resolveInstallStorePaths(),\n): string[] {\n  const retained = new Set(\n    [manifest, ...manifest.previous].map((record) => path.resolve(record.payloadPath)),\n  );\n  const removed: string[] = [];\n  for (const source of [\"npm\", \"git\"] as const) {\n    const sourceRoot = path.join(paths.installsRoot, source);\n    if (!fs.existsSync(sourceRoot)) continue;\n    const sourceStat = fs.lstatSync(sourceRoot);\n    if (!sourceStat.isDirectory() || sourceStat.isSymbolicLink()) {\n      throw new Error(`Refusing to prune unsafe install-store path ${sourceRoot}.`);\n    }\n    for (const entry of fs.readdirSync(sourceRoot)) {\n      if (entry.startsWith(\".\")) continue;\n      const candidate = path.join(sourceRoot, entry);\n      if (!retained.has(path.resolve(candidate))) {\n        fs.rmSync(candidate, { recursive: true, force: true });\n        removed.push(candidate);\n      }\n    }\n  }\n  return removed;\n}\n\nexport function assertManagedShimWritable(paths = resolveInstallStorePaths()): void {\n  const homeDir = path.dirname(path.dirname(path.dirname(paths.shimPath)));\n  for (const directoryPath of [homeDir, path.join(homeDir, \".local\"), path.dirname(paths.shimPath)]) {\n    if (!fs.existsSync(directoryPath)) continue;\n    const directoryStat = fs.lstatSync(directoryPath);","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/cli/src/install-store.ts#L319-L355","documentation":"pruneInstallPayloads lstat'ed a source root under the installs store before recursive removal and found it is not a plain directory; the guard refuses unsafe rm targets.","triggerScenarios":"Thrown at cli/src/install-store.ts:337 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Do not prune unsafe paths; verify ${sourceRoot} is inside the managed installs root."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}