Hmbown/CodeWhale · error

remote url must not start with '-'

Error message

remote url must not start with '-'

What it means

validate_git_remote_url rejects URLs beginning with '-' so the value can never be parsed as an option flag by git or a shell. This is an option-injection guard: a URL like `-oProxyCommand=...` passed to `git clone <url>` could otherwise execute attacker-controlled code.

Solutions

  1. Provide a full URL with a scheme (https:// or git@host:...) so it cannot start with '-'.
  2. Trim and validate user-supplied remote values at the boundary before storing or cloning.
  3. If you need to pass flags to git, use the dedicated option parameters, never the URL slot.
  4. Audit any code path that composes `git clone <value>` from raw user input.

Example fix

// before
let url = "-oProxyCommand=evil";
validate_git_remote_url(url)?;
// after
let url = "https://github.com/org/repo.git";
validate_git_remote_url(url)?;
Defensive patterns

Strategy: validation

Validate before calling

fn url_safe_start(raw: &str) -> bool {
    !raw.trim().starts_with('-')
}

Try / catch

match validate_git_remote_url(raw) {
    Err(e) if e.to_string().contains("must not start with '-')") => {
        eprintln!("remote URL looks like a flag; provide a full https:// or git@ URL");
    }
    other => { /* ... */ }
}

Prevention

When it happens

Trigger: Calling validate_git_remote_url / safe_git_remote_url / clone_repository with a raw string whose first non-whitespace character is '-', e.g. a malicious repo URL field, or a value where the actual URL was accidentally cut off and a flag remains.

Common situations: Security tests or fuzzed inputs starting with '-'; a truncated paste where only the tail of a command like `git clone -o ...` was captured; config values written by scripts that forgot the scheme.

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 Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/890cdecdaf09f449. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/cloud_dispatch.rs:411

/// Whether a git remote is safe to clone, show, or hand to a sandbox.
///
/// Rejects leading-dash injection (`--upload-pack=…`), embedded userinfo,
/// and network remotes that do not classify as a supported forge. Local
/// path remotes (offline fixtures) are allowed when they do not start
/// with `-` and carry no userinfo.
pub fn safe_git_remote_url(raw: &str) -> bool {
    validate_git_remote_url(raw).is_ok()
}

/// Classify and validate `job.remote_url` before any `git clone` or
/// sandbox clone. Returns the trimmed URL on success.
pub fn validate_git_remote_url(raw: &str) -> Result<String> {
    let url = raw.trim();
    if url.is_empty() || url.len() > MAX_REMOTE_BYTES {
        bail!("remote url is empty or oversized");
    }
    if url.starts_with('-') {
        bail!("remote url must not start with '-'");
    }
    if url.chars().any(char::is_control) {
        bail!("remote url contains control characters");
    }
    if remote_has_userinfo(url) {
        bail!("remote url must not embed userinfo");
    }
    if looks_like_network_git_url(url) && classify_url(url).is_none() {
        bail!("remote url is not a supported forge");
    }
    Ok(url.to_string())
}

/// Display form of a remote: userinfo is never printed.
pub fn redact_remote_url(raw: &str) -> String {
    redact_url_userinfo(raw)
}

View on GitHub (pinned to 73e0f67d83)