jdx/mise · error

relative repo paths are only allowed in a project config; us

Error message

relative repo paths are only allowed in a project config; use an absolute path or a `~/` path

What it means

Thrown by RepoRequest::from_toml while parsing an `[bootstrap.repos]` entry in mise.toml. A repo path key that is relative (not starting with `/` or `~/`) can only be resolved against a project root — the directory of the config file being read. When from_toml is called with project_root=None, which happens for the global config (~/.config/mise/mise.toml) or a standalone config file, no base directory exists, so the entry is rejected instead of silently resolving against the current working directory.

Source

Thrown at src/system/repos.rs:90

}

impl RepoRequest {
    pub fn from_toml(
        path_raw: String,
        config: RepoTomlConfig,
        project_root: Option<&Path>,
    ) -> Result<Self> {
        if path_raw.starts_with('~') && !path_raw.starts_with("~/") {
            bail!(
                "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!(

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Rewrite the repo key with a `~/` prefix (e.g. `"~/src/vendor/tool"`) for global configs
  2. Move the `[bootstrap.repos]` table into the project's mise.toml so the relative path resolves against the project root
  3. Use a fully absolute path such as `/opt/repos/tool`

Example fix

# before — ~/.config/mise/mise.toml (global config)
[bootstrap.repos]
"vendor/tool" = { url = "https://example.com/tool.git" }

# after
[bootstrap.repos]
"~/src/vendor/tool" = { url = "https://example.com/tool.git" }
Defensive patterns

Strategy: validation

Validate before calling

fn repo_path_works_without_root(path_raw: &str) -> bool {
    let p = std::path::Path::new(path_raw);
    p.is_absolute() || path_raw.starts_with("~/")
}

// before building requests from a rootless config:
for path_raw in config_repos.keys() {
    if project_root.is_none() && !repo_path_works_without_root(path_raw) {
        // would bail: rewrite to ~/… or absolute, or parse this config with a project root
    }
}

Type guard

fn is_rootless_repo_path(path_raw: &str) -> bool {
    std::path::Path::new(path_raw).is_absolute() || path_raw.starts_with("~/")
}

Prevention

When it happens

Trigger: Declaring `[bootstrap.repos]` with a key like `vendor/tool` in the global config (~/.config/mise/mise.toml) or any config parsed without a project root; any key that is not absolute and does not start with `~/`.

Common situations: Copying a project-level mise.toml snippet into the global config; declaring repos in a standalone config file (MISE_CONFIG_FILE) with no project directory; migrating a config from a repo into a dotfiles setup.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/5d0d286ceefaef00. Report an issue: GitHub.