jdx/mise · error

Git remote helpers are not supported for remote onboarding

Error message

Git remote helpers are not supported for remote onboarding

What it means

mise's remote onboarding (Source::fetch / install_at) refuses origins that look like Git remote-helper URLs (e.g. `helper::args`). During validate_origin, if the origin contains a `::` separator whose prefix is non-empty and looks like a helper name (no `/`, `\`, `[`, `]`, `@`, or `:`), onboarding is rejected because only plain HTTPS/SSH/file transports are supported.

Solutions

  1. Use a plain HTTPS or SSH URL for the origin (e.g. https://github.com/org/repo.git or git@github.com:org/repo.git).
  2. If the repo is local, pass an explicit local path (starting with ./, ../, or an absolute path) so explicit_local short-circuits the check.
  3. Set up your transport (proxy, tunnel) at the SSH/HTTP level instead of via a git remote helper.

Example fix

// before
let origin = "ext::ssh -i key user@host/repo";
Source::fetch(origin).await?;
// after
let origin = "git@github.com:org/repo.git"; // or https://...
Source::fetch(origin).await?;
Defensive patterns

Strategy: validation

Validate before calling

function is_remote_helper(origin: string): boolean {
  const i = origin.indexOf("::");
  if (i <= 0) return false;
  const prefix = origin.slice(0, i);
  return !/[\/\\\[\]@:]/.test(prefix);
}
// call Source::fetch only when !is_remote_helper(origin)

Type guard

const isPlainUrl = (s: string): s is string => /^(https|ssh|file):\/\//.test(s) && !s.includes("::");

Prevention

When it happens

Trigger: Calling Source::fetch or install_at with an origin like `git-remote-ext::...`, `ext::ssh ...`, or any `<helper>::<args>` string, when the origin is not an explicitly local path.

Common situations: Developers copying an exotic git URL (e.g. from a proxy or tunnel config) into mise.toml's source setting or the CLI flag; CI environments that rewrite remotes to helper-style URLs.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/system/remote_repository.rs:57

    Ok(String::from_utf8(output.stdout)?
        .trim_end_matches('\n')
        .to_string())
}

pub(crate) fn validate_origin(origin: &str) -> Result<()> {
    if origin.starts_with('-') || origin.chars().any(char::is_control) {
        bail!("invalid repository origin");
    }
    // Explicit local paths may contain colons; otherwise :: selects a Git helper.
    let explicit_local = std::path::Path::new(origin).is_absolute()
        || origin.starts_with("./")
        || origin.starts_with("../");
    if !explicit_local
        && origin.split_once("::").is_some_and(|(prefix, _)| {
            !prefix.is_empty() && !prefix.contains(['/', '\\', '[', ']', '@', ':'])
        })
    {
        bail!("Git remote helpers are not supported for remote onboarding");
    }
    if !explicit_local && origin.contains("://") {
        let url = url::Url::parse(origin).wrap_err("invalid repository URL")?;
        if !matches!(url.scheme(), "https" | "ssh" | "file") {
            bail!("remote bootstrap requires HTTPS, SSH, or a local path");
        }
    }
    if let Ok(url) = url::Url::parse(origin)
        && (url.password().is_some()
            || (url.scheme() != "ssh" && !url.username().is_empty())
            || url.query().is_some()
            || url.fragment().is_some())
    {
        bail!("repository origin must not contain credentials, query parameters, or fragments");
    }
    Ok(())
}

View on GitHub (pinned to 533346cc37)