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 only accepts HTTPS, SSH, or explicit local paths as repository origins. Git's 'remote helper' transport syntax (prefix::, e.g. ext:: or fork::) is blocked because spawning arbitrary helper programs would allow command execution during remote bootstrap. Origins that look like helper transports (a '::' whose prefix has no path/host characters) raise this error.

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 afd2eddd3a)

Solutions

  1. Use a standard https:// or ssh:// (scp-like user@host:path) URL instead
  2. For local repos, use an absolute path or one starting with ./ or ../
  3. If a custom transport is genuinely needed, perform that clone outside mise remote onboarding and point mise at the resulting local path

Example fix

// before
origin = "ext::ssh -i key host repo"
// after
origin = "ssh://git@host/team/repo.git"
Defensive patterns

Strategy: validation

Validate before calling

const usesRemoteHelper = (o) => { if (typeof o !== 'string') return false; const i = o.indexOf('::'); if (i < 0) return false; const prefix = o.slice(0, i); return prefix.length > 0 && ![/[\/\\]/, /[\[\]@:]/].some(rx => rx.test(prefix)); }; // reject origins where this returns true

Type guard

const isSupportedOrigin = (s) => { if (typeof s !== 'string') return false; if (/^(\.\.?\/|\/)/.test(s)) return true; if (s.includes('::')) return false; if (s.includes('://')) return /^https?:\/\//.test(s) || /^ssh:\/\//.test(s) || /^file:\/\//.test(s); return true; };

Try / catch

try { setOrigin(o); } catch (e) { console.error('Use https://, ssh://, or a local path; git remote helpers are blocked'); }

Prevention

When it happens

Trigger: Setting an origin like "ext::sh -c echo pwned" or "helper::args" in fetch/install_at where the prefix before '::' is non-empty and contains none of / \ [ ] @ : and the origin is not an explicit local path.

Common situations: Copying git remote-helper URLs from specialized tooling docs; attempting to use ext::/ssh with custom commands through mise; misusing a helper-based transport for automation.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


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