{"record":{"id":"7ba8b368ee7fcb7e","repo":"paperclipai/paperclip","slug":"registered-base-project-workspace-is-not-a-directo","errorCode":null,"errorMessage":"Registered base project workspace is not a directory at ${canonicalBaseCwd}.","messagePattern":"Registered base project workspace is not a directory at (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/shared/src/worktree-seed-source.ts","lineNumber":139,"sourceCode":"    throw new Error(\n      \"Worktree seed source is not registered. Managed boot requires a project workspace; manual boot requires --from-config.\",\n    );\n  }\n\n  let canonicalBaseCwd: string | null = null;\n  let registeredConfigPath: string | null = null;\n  if (registeredCwd) {\n    const resolvedRegisteredCwd = path.resolve(registeredCwd);\n    try {\n      canonicalBaseCwd = realpathSync(resolvedRegisteredCwd);\n    } catch {\n      throw new Error(`Registered base project workspace does not exist at ${resolvedRegisteredCwd}.`);\n    }\n    if (canonicalBaseCwd !== resolvedRegisteredCwd) {\n      throw new Error(\"Registered base project workspace must be canonical and cannot use a symlink alias.\");\n    }\n    if (!lstatSync(canonicalBaseCwd).isDirectory()) {\n      throw new Error(`Registered base project workspace is not a directory at ${canonicalBaseCwd}.`);\n    }\n    // A base workspace that is a plain checkout carries no instance config of its own.\n    // The caller's explicit source supplies it, and stays subject to every check below.\n    registeredConfigPath = baseWorkspaceDeclaresInstanceConfig(canonicalBaseCwd)\n      ? path.join(canonicalBaseCwd, \".paperclip\", \"config.json\")\n      : null;\n  }\n\n  const selectedPath = registeredConfigPath ?? explicitSource;\n  if (!selectedPath) {\n    throw new Error(\n      \"Registered base project workspace has no Paperclip config of its own and no explicit source was provided.\",\n    );\n  }\n  const canonicalSourceConfigPath = canonicalRegularFile(selectedPath, \"Registered source Paperclip config\");\n  if (registeredConfigPath && canonicalSourceConfigPath !== registeredConfigPath) {\n    throw new Error(\"Registered source Paperclip config escapes the base project workspace or uses a symlink alias.\");\n  }","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/paperclipai/paperclip/blob/a7e689b3c35347b529cb9f54c9b9a8575a3dcab6/packages/shared/src/worktree-seed-source.ts#L121-L157","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\npaperclip register --cwd ~/code/myproj/.paperclip/config.json   # a file\n\n# after\npaperclip register --cwd ~/code/myproj","handlingStrategy":"validation","validationCode":"import { statSync } from \"node:fs\";\n\nconst st = statSync(input.registeredBaseWorkspaceCwd!.trim());\nif (!st.isDirectory()) throw new Error(\"registered base workspace must be a directory\");","typeGuard":"const isDirectory = (p: string): boolean => {\n  try { return statSync(p).isDirectory(); } catch { return false; }\n};","tryCatchPattern":null,"preventionTips":["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."],"tags":["filesystem","registration","worktree-seed","not-a-directory"],"backgroundTag":"not-a-directory","analyzedSha":"a7e689b3c35347b529cb9f54c9b9a8575a3dcab6","analyzedAt":"2026-08-21T17:58:32.592Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}