paperclipai/paperclip · error
Refusing to prune unsafe install-store path
Error message
Refusing to prune unsafe install-store path ${sourceRoot}. What it means
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.
Solutions
- Do not prune unsafe paths; verify ${sourceRoot} is inside the managed installs root.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at cli/src/install-store.ts:337 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/0ad5697ce751239e.
Report an issue: GitHub.
Appendix: source
Thrown at cli/src/install-store.ts:337
.slice(0, 2);
return { schemaVersion: INSTALL_MANIFEST_VERSION, ...record, previous };
}
export function pruneInstallPayloads(
manifest: InstallManifest,
paths = resolveInstallStorePaths(),
): string[] {
const retained = new Set(
[manifest, ...manifest.previous].map((record) => path.resolve(record.payloadPath)),
);
const removed: string[] = [];
for (const source of ["npm", "git"] as const) {
const sourceRoot = path.join(paths.installsRoot, source);
if (!fs.existsSync(sourceRoot)) continue;
const sourceStat = fs.lstatSync(sourceRoot);
if (!sourceStat.isDirectory() || sourceStat.isSymbolicLink()) {
throw new Error(`Refusing to prune unsafe install-store path ${sourceRoot}.`);
}
for (const entry of fs.readdirSync(sourceRoot)) {
if (entry.startsWith(".")) continue;
const candidate = path.join(sourceRoot, entry);
if (!retained.has(path.resolve(candidate))) {
fs.rmSync(candidate, { recursive: true, force: true });
removed.push(candidate);
}
}
}
return removed;
}
export function assertManagedShimWritable(paths = resolveInstallStorePaths()): void {
const homeDir = path.dirname(path.dirname(path.dirname(paths.shimPath)));
for (const directoryPath of [homeDir, path.join(homeDir, ".local"), path.dirname(paths.shimPath)]) {
if (!fs.existsSync(directoryPath)) continue;
const directoryStat = fs.lstatSync(directoryPath);View on GitHub (pinned to 01ad858492)