{"record":{"id":"0589e6a09a1e10c4","repo":"paperclipai/paperclip","slug":"worktree-seed-manifest-is-missing-source-path-diag","errorCode":null,"errorMessage":"Worktree seed manifest is missing source path diagnostics.","messagePattern":"Worktree seed manifest is missing source path diagnostics\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/shared/src/worktree-seed-source.ts","lineNumber":211,"sourceCode":" * Resolve a worktree seed source without granting authority to the seed manifest.\n *\n * A managed caller supplies the project-workspace cwd from its server-owned row.\n * An operator may instead supply an explicit source config. A base workspace that\n * carries its own `.paperclip/config.json` stays authoritative, so an explicit path\n * must equal it; a base workspace that is a plain checkout has none, and the explicit\n * path supplies the source. Manifest source fields are diagnostic assertions only and\n * never select the returned source.\n */\nexport function resolveCanonicalWorktreeSeedSource(input: RegisteredWorktreeSeedSourceInput & {\n  manifestSource: WorktreeSeedSourceDiagnostic | null | undefined;\n  manifestTargetInstanceId?: unknown;\n}): CanonicalWorktreeSeedSource {\n  const registered = resolveRegisteredWorktreeSeedSource(input);\n  const diagnosticPath = typeof input.manifestSource?.configPath === \"string\"\n    ? input.manifestSource.configPath.trim()\n    : \"\";\n  if (!diagnosticPath) {\n    throw new Error(\"Worktree seed manifest is missing source path diagnostics.\");\n  }\n  const canonicalDiagnosticPath = canonicalRegularFile(\n    diagnosticPath,\n    \"Worktree seed manifest source diagnostic\",\n  );\n  if (path.resolve(diagnosticPath) !== registered.configPath || canonicalDiagnosticPath !== registered.configPath) {\n    throw new Error(\"Worktree seed manifest source path does not match the registered canonical source.\");\n  }\n  if (input.manifestSource?.instanceId !== registered.instanceId) {\n    throw new Error(\"Worktree seed manifest source instance does not match the registered source instance.\");\n  }\n  if (input.manifestTargetInstanceId !== registered.targetInstanceId) {\n    throw new Error(\"Worktree seed manifest target instance does not match the registered target instance.\");\n  }\n  return registered;\n}\n","sourceCodeStart":193,"sourceCodeEnd":228,"githubUrl":"https://github.com/paperclipai/paperclip/blob/a7e689b3c35347b529cb9f54c9b9a8575a3dcab6/packages/shared/src/worktree-seed-source.ts#L193-L228","documentation":"resolveCanonicalWorktreeSeedSource() first resolves the authoritative source, then cross-checks the worktree seed manifest's diagnostic fields. manifestSource.configPath must be a non-empty string; a missing, non-string, or blank value means the manifest lacks the diagnostics needed to verify it agrees with the resolved source.","triggerScenarios":"Calling resolveCanonicalWorktreeSeedSource with manifestSource null/undefined, or with configPath undefined, non-string, or whitespace-only — e.g. a manifest written by an older version that did not record source diagnostics, or hand-authored YAML/JSON missing the field.","commonSituations":"Upgrading Paperclip: manifests produced before source diagnostics existed; external tooling generating seed manifests without the source.configPath field; malformed manifest after a partial write; test fixtures omitting the field.","solutions":["Inspect the seed manifest and add/repair `source.configPath` so it names the registered canonical source config.","Regenerate the manifest with the current version of the tooling that writes source diagnostics.","If the manifest is hand-maintained, ensure configPath is a string (not null/number) and non-blank."],"exampleFix":"// before: manifest missing diagnostics\n{ \"source\": { \"instanceId\": \"...\" } }\n\n// after\n{ \"source\": { \"configPath\": \"/home/me/code/base/.paperclip/config.json\", \"instanceId\": \"...\" } }","handlingStrategy":"type-guard","validationCode":"const m = manifest.source;\nif (!m || typeof m.configPath !== \"string\" || !m.configPath.trim()) {\n  throw new Error(\"seed manifest lacks source.configPath — regenerate the manifest\");\n}","typeGuard":"const hasSourceDiagnostics = (\n  m: WorktreeSeedSourceDiagnostic | null | undefined,\n): m is { configPath: string; instanceId: string } =>\n  typeof m?.configPath === \"string\" && m.configPath.trim().length > 0 &&\n  typeof m.instanceId === \"string\";","tryCatchPattern":null,"preventionTips":["Regenerate manifests with tooling that always writes source.configPath.","Validate manifests against a schema (zod/json-schema) at load time.","Treat manifests from older versions as stale; rebuild rather than patch."],"tags":["manifest","worktree-seed","validation","schema"],"backgroundTag":"missing-manifest-field","analyzedSha":"a7e689b3c35347b529cb9f54c9b9a8575a3dcab6","analyzedAt":"2026-08-21T17:58:32.592Z","contentChangedAt":"2026-08-21T17:58:32.592Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}