{"record":{"id":"8ae801ec9ac24f0d","repo":"coleam00/Archon","slug":"archon-config-yaml-worktree-path-must-stay-within","errorCode":null,"errorMessage":".archon/config.yaml worktree.path must stay within the repo (got: ${trimmed}). Remove any `..` segments.","messagePattern":"\\.archon/config\\.yaml worktree\\.path must stay within the repo \\(got: (.+?)\\)\\. Remove any `\\.\\.` segments\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/isolation/src/providers/worktree.ts","lineNumber":127,"sourceCode":"  if (!trimmed) return undefined;\n\n  if (isAbsolute(trimmed)) {\n    throw new Error(\n      `.archon/config.yaml worktree.path must be relative to the repo root (got absolute: ${trimmed}). ` +\n        'For an absolute location, set ~/.archon/config.yaml paths.worktrees instead.'\n    );\n  }\n\n  const normalized = normalizePath(trimmed);\n  // A plain `..` or anything that starts with `../` or contains `/../` escapes the repo.\n  if (\n    normalized === '..' ||\n    normalized.startsWith('../') ||\n    normalized.startsWith('..\\\\') ||\n    normalized.includes('/../') ||\n    normalized.includes('\\\\..\\\\')\n  ) {\n    throw new Error(\n      `.archon/config.yaml worktree.path must stay within the repo (got: ${trimmed}). ` +\n        'Remove any `..` segments.'\n    );\n  }\n\n  // Double-check via resolved absolute paths — catches edge cases like a path that\n  // normalizes clean but still escapes when joined (e.g. leading `./../` on some platforms).\n  // Uses `path.sep` so the \"is inside repoRoot\" check works on Windows (\\\\) as well as POSIX (/).\n  const resolved = resolve(repoRoot, normalized);\n  const repoRootResolved = resolve(repoRoot);\n  if (resolved !== repoRootResolved && !resolved.startsWith(repoRootResolved + sep)) {\n    throw new Error(\n      `.archon/config.yaml worktree.path resolves outside the repo root (got: ${trimmed} → ${resolved}).`\n    );\n  }\n\n  return normalized;\n}","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/coleam00/Archon/blob/0773b9745896ef0612e709c80845a0f7db315b19/packages/isolation/src/providers/worktree.ts#L109-L145","documentation":"WorktreeProvider validates the optional `worktree.path` override in `.archon/config.yaml` before using it as the worktree base directory. A value containing a `..` segment would place worktrees outside the repository, which the per-repo override is not allowed to do. This fail-fast check runs during path resolution in resolveRepoLocalOverride.","triggerScenarios":"Setting `worktree.path` in `.archon/config.yaml` to a value like `../worktrees`, `..`, `foo/../..`, or any path whose normalized form starts with or contains a `..` segment, then triggering worktree creation (WorktreeProvider.create / getWorktreePath).","commonSituations":"Developers trying to share one worktree directory across several repos by pointing the path at a sibling folder; copying a global absolute-style location into the per-repo config; typos like `./../worktrees`.","solutions":["Remove all `..` segments from `worktree.path` and use a path relative to and inside the repo root, e.g. `.worktrees`","If you need worktrees outside the repo, set an absolute location in the global `~/.archon/config.yaml` under `paths.worktrees` instead","Delete the `worktree.path` key entirely to fall back to default worktree path resolution"],"exampleFix":"# before (.archon/config.yaml)\nworktree:\n  path: ../shared-worktrees\n# after\nworktree:\n  path: .worktrees","handlingStrategy":"validation","validationCode":"import { isAbsolute, resolve, sep } from 'node:path';\nexport function validateWorktreePath(rawPath: string | undefined, repoRoot: string): void {\n  const t = rawPath?.trim();\n  if (!t) return;\n  if (isAbsolute(t)) throw new Error(`worktree.path must be relative: ${t}`);\n  const normalized = t.replace(/\\\\/g, '/');\n  if (normalized === '..' || normalized.startsWith('../') || normalized.includes('/../')) {\n    throw new Error(`worktree.path must stay within the repo: ${t}`);\n  }\n  const resolved = resolve(repoRoot, t);\n  if (!resolved.startsWith(resolve(repoRoot) + sep)) {\n    throw new Error(`worktree.path resolves outside repo: ${t} -> ${resolved}`);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep worktree.path a simple relative directory like `.worktrees`","Never use `..` in per-repo overrides; use the global config for outside locations","Lint `.archon/config.yaml` in CI with a path-validation check"],"tags":["config","path-validation","worktree","fail-fast"],"backgroundTag":"config-path-escapes-repo-root","analyzedSha":"0773b9745896ef0612e709c80845a0f7db315b19","analyzedAt":"2026-09-01T02:28:07.064Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}