paperclipai/paperclip · error · Error
Registered base project workspace is not a directory at ${ca
Error message
Registered base project workspace is not a directory at ${canonicalBaseCwd}. What it means
The registered base workspace cwd resolves fine but lstat says it is not a directory (a regular file, FIFO, etc.). A base workspace must be a directory because the resolver looks for `.paperclip/config.json` inside it and uses it to anchor worktrees.
Source
Thrown at packages/shared/src/worktree-seed-source.ts:139
throw new Error(
"Worktree seed source is not registered. Managed boot requires a project workspace; manual boot requires --from-config.",
);
}
let canonicalBaseCwd: string | null = null;
let registeredConfigPath: string | null = null;
if (registeredCwd) {
const resolvedRegisteredCwd = path.resolve(registeredCwd);
try {
canonicalBaseCwd = realpathSync(resolvedRegisteredCwd);
} catch {
throw new Error(`Registered base project workspace does not exist at ${resolvedRegisteredCwd}.`);
}
if (canonicalBaseCwd !== resolvedRegisteredCwd) {
throw new Error("Registered base project workspace must be canonical and cannot use a symlink alias.");
}
if (!lstatSync(canonicalBaseCwd).isDirectory()) {
throw new Error(`Registered base project workspace is not a directory at ${canonicalBaseCwd}.`);
}
// A base workspace that is a plain checkout carries no instance config of its own.
// The caller's explicit source supplies it, and stays subject to every check below.
registeredConfigPath = baseWorkspaceDeclaresInstanceConfig(canonicalBaseCwd)
? path.join(canonicalBaseCwd, ".paperclip", "config.json")
: null;
}
const selectedPath = registeredConfigPath ?? explicitSource;
if (!selectedPath) {
throw new Error(
"Registered base project workspace has no Paperclip config of its own and no explicit source was provided.",
);
}
const canonicalSourceConfigPath = canonicalRegularFile(selectedPath, "Registered source Paperclip config");
if (registeredConfigPath && canonicalSourceConfigPath !== registeredConfigPath) {
throw new Error("Registered source Paperclip config escapes the base project workspace or uses a symlink alias.");
}View on GitHub (pinned to a7e689b3c3)
Solutions
- Inspect what is at the path: `ls -la <canonicalBaseCwd>` / `file <canonicalBaseCwd>`.
- If a file occupies the path, remove/rename it and restore the actual workspace directory.
- Re-register pointing at the checkout's root directory, not at any file inside it.
Example fix
# before paperclip register --cwd ~/code/myproj/.paperclip/config.json # a file # after paperclip register --cwd ~/code/myproj
Defensive patterns
Strategy: validation
Validate before calling
import { statSync } from "node:fs";
const st = statSync(input.registeredBaseWorkspaceCwd!.trim());
if (!st.isDirectory()) throw new Error("registered base workspace must be a directory"); Type guard
const isDirectory = (p: string): boolean => {
try { return statSync(p).isDirectory(); } catch { return false; }
}; Prevention
- Registration commands should stat-and-validate the cwd is a directory before saving it.
- Never pass a file path (config, script) as the workspace cwd.
- Cover this case in CLI integration tests.
When it happens
Trigger: registering a workspace whose cwd is actually a file (e.g. a config or script path passed instead of its directory); a special node placed at the recorded path; a path that changed from directory to file after registration.
Common situations: Passing a path with a trailing `/config.json` to a registration command; provisioning scripts creating a marker file where the directory should be; artifacts unpacked over the workspace path.
Related errors
- Registered base project workspace does not exist at ${resolv
- Registered base project workspace Paperclip config at ${conf
- ${label} does not exist at ${resolved}.
- ${label} must be a canonical path and cannot use a symlink a
- ${label} is not a regular file at ${canonical}.
AI-assisted analysis of paperclipai/paperclip@a7e689b3c3 (2026-08-21).
Data as JSON: /api/errors/7ba8b368ee7fcb7e.
Report an issue: GitHub.