paperclipai/paperclip · error
Refusing to activate non-directory payload
Error message
Refusing to activate non-directory payload ${payloadPath}. What it means
assertPayloadPath lstat'ed the payload to activate and it is not a plain directory (symlink or file); a safety guard before flipping the current symlink.
Solutions
- Ensure the payload at ${payloadPath} is a directory before activation.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at cli/src/install-store.ts:254 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/26c5352700d4df47.
Report an issue: GitHub.
Appendix: source
Thrown at cli/src/install-store.ts:254
): void {
ensurePrivateDirectory(paths.cliRoot);
const temporaryPath = `${paths.manifestPath}.tmp-${process.pid}-${Date.now()}`;
try {
fs.writeFileSync(temporaryPath, `${JSON.stringify(manifest, null, 2)}\n`, { mode: 0o600 });
fs.renameSync(temporaryPath, paths.manifestPath);
} finally {
fs.rmSync(temporaryPath, { force: true });
}
}
function assertPayloadPath(payloadPath: string, paths: InstallStorePaths): void {
const relative = path.relative(paths.installsRoot, path.resolve(payloadPath));
if (!relative || relative.startsWith("..") || path.isAbsolute(relative)) {
throw new Error(`Refusing to activate payload outside ${paths.installsRoot}.`);
}
const stat = fs.lstatSync(payloadPath);
if (!stat.isDirectory() || stat.isSymbolicLink()) {
throw new Error(`Refusing to activate non-directory payload ${payloadPath}.`);
}
const installsRealPath = fs.realpathSync(paths.installsRoot);
const payloadRealPath = fs.realpathSync(payloadPath);
if (!payloadRealPath.startsWith(`${installsRealPath}${path.sep}`)) {
throw new Error(`Refusing to activate payload that resolves outside ${paths.installsRoot}.`);
}
}
export function flipCurrentAtomic(
payloadPath: string,
paths = resolveInstallStorePaths(),
hooks: { beforeRename?: () => void } = {},
): void {
assertPayloadPath(payloadPath, paths);
ensurePrivateDirectory(paths.cliRoot);
try {
const currentStat = fs.lstatSync(paths.currentPath);
if (!currentStat.isSymbolicLink()) {View on GitHub (pinned to 01ad858492)