{"record":{"id":"014dc86293516ea6","repo":"paperclipai/paperclip","slug":"registered-base-project-workspace-has-no-paperclip","errorCode":null,"errorMessage":"Registered base project workspace has no Paperclip config of its own and no explicit source was provided.","messagePattern":"Registered base project workspace has no Paperclip config of its own and no explicit source was provided\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/shared/src/worktree-seed-source.ts","lineNumber":150,"sourceCode":"    } 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  }\n\n  if (explicitSource) {\n    const canonicalExplicitSource = canonicalRegularFile(explicitSource, \"Explicit source Paperclip config\");\n    if (canonicalExplicitSource !== canonicalSourceConfigPath) {\n      throw new Error(\"Explicit source Paperclip config does not match the registered base project workspace.\");\n    }\n  }\n\n  const canonicalTargetConfigPath = canonicalRegularFile(\n    input.targetConfigPath,\n    \"Target worktree Paperclip config\",","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/paperclipai/paperclip/blob/a7e689b3c35347b529cb9f54c9b9a8575a3dcab6/packages/shared/src/worktree-seed-source.ts#L132-L168","documentation":"The base workspace exists and is canonical, but declares no instance config of its own (no `.paperclip` entry), and no explicit --from-config was provided, so there is no selectable seed source. A plain checkout can serve as a base only when the caller explicitly names where to seed from.","triggerScenarios":"Managed boot inside a plain git checkout of the project (never registered with a `.paperclip/config.json`) with the explicitSourceConfigPath argument omitted; baseWorkspaceDeclaresInstanceConfig() returning false and explicitSource empty.","commonSituations":"Fresh clone used as the base workspace; `.paperclip` directory deleted or never created; teams sharing a checkout without instance registration; scripts that assume managed boot works from any clone.","solutions":["Pass an explicit source: add `--from-config <instance>/config.json` to the seed/boot command.","Or give the base workspace its own instance config: create `.paperclip/config.json` (via the register/init flow) so it declares an instance.","Verify the `.paperclip` entry actually exists at the workspace root (`ls -la <base>/.paperclip`); note a fully absent entry is treated as 'no config', while a broken symlink entry throws earlier."],"exampleFix":"# before: plain checkout, no .paperclip, no flag\npaperclip worktree seed\n\n# after\npaperclip worktree seed --from-config ~/.paperclip/instances/<instance-id>/config.json","handlingStrategy":"validation","validationCode":"import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\n\nconst declaresConfig = (base: string) =>\n  existsSync(path.join(base, \".paperclip\", \"config.json\")) || existsSync(path.join(base, \".paperclip\"));\n\nif (!declaresConfig(base) && !explicitSource) {\n  throw new Error(\"plain checkout: pass --from-config to name the seed source\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Standardize team scripts to always pass --from-config for plain checkouts.","Or register checkouts once so `.paperclip/config.json` exists.","Surface a helpful hint in CLI wrappers when running in an unregistered directory."],"tags":["worktree-seed","config","missing-config","cli"],"backgroundTag":"missing-config-file","analyzedSha":"a7e689b3c35347b529cb9f54c9b9a8575a3dcab6","analyzedAt":"2026-08-21T17:58:32.592Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}