jdx/mise · error
relative repo path ` ` must stay within the project root…
Error message
relative repo path `{path_raw}` must stay within the project root (no `..` or absolute segments) What it means
RepoRequest::from_toml validates `[bootstrap.repos]` entries. When a repo key is a relative path, the expanded path must resolve inside the project root: any `..`, root, or platform-prefix component is rejected before the path is joined to the root. This blocks entries from pointing outside the project via traversal.
Solutions
- Change the key to an absolute path or a `~/`-relative path (e.g. `"~/src/dotfiles"`), which bypasses the project-root containment check
- Move the target repo inside the project directory and use a plain relative key like `"tools/repo"`
- Remove `..` segments from the key so it stays within the project root
Example fix
// before
[bootstrap.repos]
"../dotfiles" = { url = "https://github.com/jdx/dotfiles.git" }
// after
[bootstrap.repos]
"~/src/dotfiles" = { url = "https://github.com/jdx/dotfiles.git" } Defensive patterns
Strategy: validation
Validate before calling
fn is_safe_relative_repo_path(p: &str) -> bool {
let path = std::path::Path::new(p);
!(path.is_absolute())
&& !path.components().any(|c| matches!(c, std::path::Component::ParentDir | std::path::Component::RootDir | std::path::Component::Prefix(_)))
}
// assert!(is_safe_relative_repo_path("tools/repo")) Type guard
fn is_project_relative(p: &str) -> Option<&str> {
let path = std::path::Path::new(p);
if path.is_absolute() || p.starts_with('~') { return None; }
if path.components().any(|c| !matches!(c, std::path::Component::Normal(_) | std::path::Component::CurDir)) { return None; }
Some(p)
} Prevention
- Use `~/`-relative keys for repos outside the project; keep relative keys strictly inside the project tree
- Never use `..` in repo path keys; restructure the layout instead
- Test mise.toml parsing after moving entries between global and project configs
When it happens
Trigger: Defining a bootstrap repo key like `"../shared/repo" = { url = ... }` in a project mise.toml; the relative path expands to a path containing a ParentDir component.
Common situations: Copying a repo entry from a global config into a project config without making it `~/`-relative or absolute; typos like `..\tools` on Windows; intentionally trying to check out a repo that lives in a sibling directory of the project.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- must set a non-empty `url`
- must set `url`
- `ref` must not be empty
- relative repo path ` ` must name a directory inside the…
- an implied source entry key must not contain '..'
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/738ec9c87cdcf9c1.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/repos.rs:100
"repo path `{path_raw}` cannot start with `~`; use `~/` for a home-relative path"
);
}
let path = file::replace_path(&path_raw);
let path = if path.is_absolute() {
path
} else {
let Some(root) = project_root else {
bail!(
"relative repo paths are only allowed in a project config; use an absolute path or a `~/` path"
);
};
if path.components().any(|component| {
matches!(
component,
Component::ParentDir | Component::RootDir | Component::Prefix(_)
)
}) {
bail!(
"relative repo path `{path_raw}` must stay within the project root (no `..` or absolute segments)"
);
}
if !path
.components()
.any(|component| matches!(component, Component::Normal(_)))
{
bail!(
"relative repo path `{path_raw}` must name a directory inside the project root"
);
}
// Join only the Normal segments so `./foobar` resolves to
// `<root>/foobar` rather than `<root>/./foobar` — a `.` component
// survives `Path::join` and leaks into every displayed path.
let mut resolved = root.to_path_buf();
for component in path.components() {
if let Component::Normal(segment) = component {
resolved.push(segment);View on GitHub (pinned to 533346cc37)