jdx/mise · error

invalid repository origin

Error message

invalid repository origin

What it means

`validate_origin` screens the repository origin before it is passed to git: it must not start with '-' (which git would parse as a flag, enabling argument injection) and must contain no control characters. Non-explicit-local origins (not absolute/./.. paths) must further be a valid remote URL form (an scp-like or URL scheme selected by '::'). Failing these checks throws this error.

Solutions

  1. Correct the origin to a valid git URL (https://..., git@host:path, ssh://...) or an explicit local path (absolute, ./, or ../)
  2. Remove any leading '-' and control characters from the configured origin
  3. Re-check the remote.toml/config encoding (save as clean UTF-8) if invisible characters are suspected

Example fix

// before
origin = "-u evil.com/repo.git"
// after
origin = 'https://evil.com/repo.git'
Defensive patterns

Strategy: validation

Validate before calling

function isValidOrigin(o) {
  if (typeof o !== 'string' || o.startsWith('-') || /[\x00-\x1f]/.test(o)) return false;
  if (/^(\/|\.\.?\/)/.test(o)) return true; // explicit local path
  return /^(ssh|https?|git|file):\/\//.test(o) || /^[^\s:]+:[^\/]/.test(o); // URL or scp-like
}

Type guard

const isSafeOrigin = (o: unknown): o is string =>
  typeof o === 'string' && !o.startsWith('-') && !/[\x00-\x1f]/.test(o) && o.length > 0;

Try / catch

try { validate_origin(origin)?; } catch (e) {
  // prompt user for a corrected git URL before any git invocation
}

Prevention

When it happens

Trigger: Configuring an origin like '-upload-pack=evil', a string with embedded control bytes, or a non-local value that is neither a valid URL nor scp-like syntax (no scheme/colon pattern).

Common situations: Typo'd remote URLs; copy-paste introducing invisible control characters; attempts to pass extra git flags through the origin; writing a bare hostname without the required URL/scp form.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at src/system/remote_repository.rs:46

async fn git_async(path: &Path, args: &[&str]) -> Result<String> {
    let mut command = Command::new("git");
    crate::git::sanitize_git_command(&mut command);
    command.arg("-C").arg(path).args(args);
    let output = tokio::process::Command::from(command)
        .kill_on_drop(true)
        .output()
        .await?;
    if !output.status.success() {
        bail!("repository operation failed ({})", output.status);
    }
    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");
        }
    }

View on GitHub (pinned to 533346cc37)