jdx/mise · error

workspace path is absolute; paths must be workspace-relative

Error message

workspace path {path:?} is absolute; paths must be workspace-relative

What it means

normalize_workspace_path validates general workspace-relative paths (used for workspace files/patterns). Absolute paths are rejected because workspace paths are always resolved against the workspace root; an absolute value would bypass that anchoring, so mise throws this error.

Solutions

  1. Rewrite the path relative to the workspace root
  2. Compute the relative path from the workspace root programmatically (e.g. pathdiff) before writing config
  3. Check that env-var or template expansion in the config is not injecting absolute paths

Example fix

# before
workspace_files = ["/home/me/proj/mise.toml"]
# after
workspace_files = ["mise.toml"]
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_relative_workspace_path(p: &std::path::Path) -> Result<(), String> {
    if p.is_absolute() {
        return Err(format!("workspace path {p:?} must be workspace-relative"));
    }
    Ok(())
}

Type guard

let rel = |p: &std::path::Path| !p.is_absolute();

Try / catch

if let Err(e) = normalize_workspace_path(&p) {
    if e.to_string().contains("is absolute") {
        let rel = p.strip_prefix(&ws_root).unwrap_or(&p);
        eprintln!("use {rel:?} instead");
    }
}

Prevention

When it happens

Trigger: Passing a Path like "/etc/foo" or "C:\\foo" to a workspace path field (e.g. include/exclude/file lists) that flows through normalize_workspace_path.

Common situations: Absolute paths produced by tooling or environment expansion ending up in workspace config path lists; copy-pasting absolute paths from logs.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/d5a7f90a633f1797. Report an issue: GitHub.

Appendix: 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 533346cc37)