jdx/mise · error
workspace path {path:?} is absolute; paths must be workspace
Error message
workspace path {path:?} is absolute; paths must be workspace-relative What it means
normalize_workspace_path() validates every path handed to map_paths_to_projects() / affected_projects_for_paths(): paths must be workspace-relative, and an absolute path is rejected up front. Internally mise always strips the workspace-root prefix before calling these APIs, so a developer calling the graph API directly with filesystem paths (e.g. from a file watcher) hits this check.
Source
Thrown at src/task/workspace.rs:1222
);
}
}
Component::RootDir | Component::Prefix(_) => {
bail!(
"workspace project {id:?} has absolute root {root:?}; roots must be workspace-relative"
);
}
}
}
if normalized.as_os_str().is_empty() {
normalized.push(".");
}
Ok(normalized)
}
fn normalize_workspace_path(path: &Path) -> Result<PathBuf> {
if path.is_absolute() {
bail!("workspace path {path:?} is absolute; paths must be workspace-relative");
}
let mut normalized = PathBuf::new();
for component in path.components() {
match component {
Component::CurDir => {}
Component::Normal(component) => normalized.push(component),
Component::ParentDir => {
if !normalized.pop() {
bail!("workspace path {path:?} escapes the workspace root");
}
}
Component::RootDir | Component::Prefix(_) => {
bail!("workspace path {path:?} is absolute; paths must be workspace-relative");
}
}
}
if normalized.as_os_str().is_empty() {View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Strip the workspace root first: path.strip_prefix(workspace_root) before passing
- Emit relative paths at the source (e.g. git -C root diff --relative --name-only)
- Filter or skip paths outside the workspace root — they cannot map to projects anyway
Example fix
// before
let map = graph.map_paths_to_projects(["/repo/crates/app/src/lib.rs"])?;
// after
let rel = Path::new("/repo/crates/app/src/lib.rs").strip_prefix("/repo")?;
let map = graph.map_paths_to_projects([rel])?; Defensive patterns
Strategy: validation
Validate before calling
let rel_paths: Vec<PathBuf> = paths.iter()
.filter_map(|p| p.strip_prefix(workspace_root).ok().map(Path::to_path_buf))
.collect();
let map = graph.map_paths_to_projects(rel_paths)?; Type guard
fn all_paths_workspace_relative<'a>(root: &Path, paths: impl IntoIterator<Item = &'a Path>) -> bool {
paths.into_iter().all(|p| !p.is_absolute())
} Try / catch
match graph.affected_projects_for_paths(root, paths, global_inputs) {
Ok(set) => set,
Err(err) if err.to_string().contains("is absolute") => {
let rel: Vec<_> = paths.into_iter().filter_map(|p| p.strip_prefix(root).ok()).collect();
graph.affected_projects_for_paths(root, rel, global_inputs)?
}
Err(err) => return Err(err),
} Prevention
- Convert watcher/diff output with strip_prefix(workspace_root) before calling graph APIs
- Run git as git -C <workspace-root> diff --relative --name-only
- Drop paths outside the workspace root — they can never map to a project
When it happens
Trigger: Calling graph.map_paths_to_projects(["/home/me/repo/src/main.rs"]) or affected_projects_for_paths(root, [absolute_path], ...) with un-stripped absolute paths; feeding paths from notify/inotify watchers, git diff --name-only run from another cwd, or canonicalized paths.
Common situations: Integrating file-watch/build tooling that natively produces absolute paths; assuming the API takes workspace-rooted absolute paths; inconsistent cwd between path production and graph use.
Related errors
- workspace project {id:?} has absolute root {root:?}; roots m
- workspace project {id:?} has root {root:?} that escapes the
- workspace path {path:?} escapes the workspace root
- Cargo workspace member pattern {member:?} must be relative
- mise upgrade --monorepo is not implemented yet
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/d5a7f90a633f1797.
Report an issue: GitHub.