{"record":{"id":"0297ffd82d1d3bf6","repo":"coleam00/Archon","slug":"archon-config-yaml-worktree-path-resolves-outside","errorCode":null,"errorMessage":".archon/config.yaml worktree.path resolves outside the repo root (got: ${trimmed} → ${resolved}).","messagePattern":"\\.archon/config\\.yaml worktree\\.path resolves outside the repo root \\(got: (.+?) → (.+?)\\)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/isolation/src/providers/worktree.ts","lineNumber":139,"sourceCode":"    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}\n\nexport class WorktreeProvider implements IIsolationProvider {\n  readonly providerType = 'worktree';\n\n  constructor(private loadConfig: RepoConfigLoader = () => Promise.resolve(null)) {}\n\n  /**\n   * Create an isolated environment using git worktrees.\n   *\n   * Config is loaded exactly once here and threaded through the rest of the\n   * `create()` call. A malformed `.archon/config.yaml` fails loudly at this\n   * boundary rather than being swallowed — see CLAUDE.md \"Fail Fast + Explicit","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/coleam00/Archon/blob/0773b9745896ef0612e709c80845a0f7db315b19/packages/isolation/src/providers/worktree.ts#L121-L157","documentation":"Even after the textual `..`-segment check, resolveRepoLocalOverride re-resolves the configured `worktree.path` against the repo root using absolute paths and confirms the result stays inside the repo. This catches edge cases that normalize clean textually but still escape when joined (e.g. leading `./../` or symlink-like segments).","triggerScenarios":"A `worktree.path` such as `./../outside` or any value whose `path.resolve(repoRoot, value)` result is neither equal to the resolved repo root nor prefixed by `repoRoot + path.sep`, on Windows or POSIX.","commonSituations":"Platform-specific separator confusion (`..\\foo` on POSIX), copying configs between machines with different repo layouts, values that pass a naive string check but resolve outside the tree.","solutions":["Change `worktree.path` so it resolves to a directory inside the repository, e.g. `.worktrees`","Use the global `~/.archon/config.yaml` `paths.worktrees` for an absolute outside-the-repo location","Print `path.resolve(repoRoot, value)` locally to see where the configured value actually lands, then adjust"],"exampleFix":"// before\nworktree:\n  path: ./../archon-worktrees\n// after\nworktree:\n  path: .archon-worktrees","handlingStrategy":"validation","validationCode":"import { resolve, sep } from 'node:path';\nexport function isInsideRepo(candidate: string, repoRoot: string): boolean {\n  const resolved = resolve(repoRoot, candidate);\n  const root = resolve(repoRoot);\n  return resolved === root || resolved.startsWith(root + sep);\n}\n// call before relying on the config: if (!isInsideRepo(cfg.worktree.path, repoRoot)) throw ...","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Resolve the configured path locally (path.resolve) before committing the config","Beware Windows `..\\` segments when sharing configs across platforms","Test configs on each OS you develop on"],"tags":["config","path-traversal","worktree","cross-platform"],"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"}