{"record":{"id":"2dcbe10f9417ab61","repo":"clockworklabs/SpacetimeDB","slug":"path-is-outside-repo-root","errorCode":null,"errorMessage":"Path {} is outside repo root {}","messagePattern":"Path (.+?) is outside repo root (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/build.rs","lineNumber":388,"sourceCode":"/// and transform it into an absolute, canonical path.\nfn get_full_path_within_manifest_dir(relative_path: &Path, _manifest_dir: &Path) -> PathBuf {\n    let repo_root = get_repo_root();\n    let full_path = repo_root.join(\"templates\").join(relative_path);\n\n    full_path.canonicalize().unwrap_or_else(|e| {\n        panic!(\"Failed to canonicalize path {}: {}\", full_path.display(), e);\n    })\n}\n\n/// Transform `full_path` into a relative path within `repo_root`.\n///\n/// `full_path` and `repo_root` should both be canonical paths, as by [`Path::canonicalize`].\nfn make_repo_root_relative(full_path: &Path, repo_root: &Path) -> PathBuf {\n    full_path\n        .strip_prefix(repo_root)\n        .map(|p| p.to_path_buf())\n        .unwrap_or_else(|_| {\n            panic!(\n                \"Path {} is outside repo root {}\",\n                full_path.display(),\n                repo_root.display()\n            )\n        })\n}\n\nfn get_git_tracked_files_via_cli(path: &Path, manifest_dir: &Path) -> (Vec<PathBuf>, PathBuf) {\n    let repo_root = get_repo_root();\n    let repo_root = repo_root.canonicalize().unwrap_or_else(|err| {\n        panic!(\n            \"Failed to canonicalize repo_root path {}: {err:#?}\",\n            repo_root.display(),\n        )\n    });\n\n    let resolved_path = make_repo_root_relative(&get_full_path_within_manifest_dir(path, manifest_dir), &repo_root);\n","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/cli/build.rs#L370-L406","documentation":"Build-time panic in crates/cli/build.rs: `make_repo_root_relative` could not strip the repo-root prefix from a discovered template file, meaning the file's canonical path lies outside the repository root. Embedded template files are stored as repo-relative paths; a path that escapes the root breaks that invariant, so the build panics instead of embedding an unusable path. The usual culprit is a symlink inside templates/ resolving to a location outside the checkout.","triggerScenarios":"A symlink under templates/ (or repo root) pointing to an absolute path or a directory above the repo root; canonicalization resolving through a symlinked templates directory that actually lives elsewhere; a repo root computed from a moved directory.","commonSituations":"Developers symlinking shared template folders into their checkout; monorepo tooling that links external assets; building after relocating the repo while stale absolute symlinks remain.","solutions":["Find escaping links: `find templates -type l -exec readlink -f {} \\; | grep -v \"^$(pwd)/\"` and remove or replace them with real copies.","Keep all embedded template content physically inside the repository.","Re-check the panic's two printed paths — if repo_root itself looks wrong, see the get_repo_root failure (build from the standard checkout layout).","Re-run the build after replacing symlinks with actual files (`cp -L`)."],"exampleFix":"# before\nln -s /shared/templates/my-template templates/my-template\n\n# after\ncp -r /shared/templates/my-template templates/my-template\ngit add templates/my-template","handlingStrategy":"validation","validationCode":"# Fail if any template path canonicalizes outside the repo root:\nroot=$(git rev-parse --show-toplevel)\nfind templates -type l | while read -r l; do\n  tgt=$(readlink -f \"$l\")\n  case \"$tgt\" in \"$root\"/*) ;; *) echo \"escaping symlink: $l -> $tgt\";; esac\ndone","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never symlink external content into templates/; copy it in and commit.","Run the escaping-symlink check in CI.","Keep the repo at the standard layout so the computed repo root is correct."],"tags":["spacetimedb","build-script","symlink","path-escape","templates"],"backgroundTag":"path-outside-workspace","analyzedSha":"6dee26c6efc2856793e12b148a59742964f5d783","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}