clockworklabs/SpacetimeDB · error
Path {} is outside repo root {}
Error message
Path {} is outside repo root {} What it means
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.
Source
Thrown at crates/cli/build.rs:388
/// and transform it into an absolute, canonical path.
fn get_full_path_within_manifest_dir(relative_path: &Path, _manifest_dir: &Path) -> PathBuf {
let repo_root = get_repo_root();
let full_path = repo_root.join("templates").join(relative_path);
full_path.canonicalize().unwrap_or_else(|e| {
panic!("Failed to canonicalize path {}: {}", full_path.display(), e);
})
}
/// Transform `full_path` into a relative path within `repo_root`.
///
/// `full_path` and `repo_root` should both be canonical paths, as by [`Path::canonicalize`].
fn make_repo_root_relative(full_path: &Path, repo_root: &Path) -> PathBuf {
full_path
.strip_prefix(repo_root)
.map(|p| p.to_path_buf())
.unwrap_or_else(|_| {
panic!(
"Path {} is outside repo root {}",
full_path.display(),
repo_root.display()
)
})
}
fn get_git_tracked_files_via_cli(path: &Path, manifest_dir: &Path) -> (Vec<PathBuf>, PathBuf) {
let repo_root = get_repo_root();
let repo_root = repo_root.canonicalize().unwrap_or_else(|err| {
panic!(
"Failed to canonicalize repo_root path {}: {err:#?}",
repo_root.display(),
)
});
let resolved_path = make_repo_root_relative(&get_full_path_within_manifest_dir(path, manifest_dir), &repo_root);
View on GitHub (pinned to 6dee26c6ef)
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`).
Example fix
# before ln -s /shared/templates/my-template templates/my-template # after cp -r /shared/templates/my-template templates/my-template git add templates/my-template
Defensive patterns
Strategy: validation
Validate before calling
# Fail if any template path canonicalizes outside the repo root: root=$(git rev-parse --show-toplevel) find templates -type l | while read -r l; do tgt=$(readlink -f "$l") case "$tgt" in "$root"/*) ;; *) echo "escaping symlink: $l -> $tgt";; esac done
Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Developers symlinking shared template folders into their checkout; monorepo tooling that links external assets; building after relocating the repo while stale absolute symlinks remain.
Related errors
- Template '{}' has no git-tracked files! Check that the direc
- Failed to read_dir from template directory {}: {err:#?}
- Got error during read_dir from template directory {}: {err:#
- Failed to get file_type for template file {}: {err:#?}
- Failed to canonicalize path {}: {}
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/2dcbe10f9417ab61.
Report an issue: GitHub.