Hmbown/CodeWhale · error

remote url contains control characters

Error message

remote url contains control characters

What it means

validate_git_remote_url rejects URLs containing control characters (per char::is_control). Control bytes in a URL can smuggle newlines, escapes, or terminal sequences into git commands and logs, so they are refused before any clone.

Solutions

  1. Trim and strip control characters (or reject) at input time before validation.
  2. Re-enter the URL as a single clean line; copy it from the forge's official clone widget.
  3. If reading from a file, normalize line endings and split on whitespace, taking one token.
  4. Log the sanitized value when reporting the failure; never echo raw control bytes.

Example fix

// before
let url = format!("https://github.com/org/repo.git\n{}");
validate_git_remote_url(&url)?;
// after
let url = raw.trim().chars().filter(|c| !c.is_control()).collect::<String>();
validate_git_remote_url(&url)?;
Defensive patterns

Strategy: validation

Validate before calling

fn has_control_chars(s: &str) -> bool {
    s.chars().any(char::is_control)
}

Type guard

fn clean_url(s: &str) -> Option<String> {
    let cleaned: String = s.trim().chars().filter(|c| !c.is_control()).collect();
    (cleaned == s.trim()).then_some(cleaned)
}

Try / catch

match validate_git_remote_url(raw) {
    Err(e) if e.to_string().contains("control characters") => {
        let sanitized = raw.trim().chars().filter(|c| !c.is_control()).collect::<String>();
        eprintln!("URL contained control chars; sanitized: {sanitized}");
    }
    other => { /* ... */ }
}

Prevention

When it happens

Trigger: Calling validate_git_remote_url / safe_git_remote_url / clone_repository with a string containing e.g. \n, \r, \t, or other C0/C1 control bytes — typically from multiline paste, binary-corrupted config, or concatenation with log output.

Common situations: Pasting a URL from a terminal where a line wrap introduced a newline; reading a value from a file that kept a trailing \r (CRLF); string building that accidentally joined a URL with log lines.

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/0a16aee07e9cfb45. Report an issue: GitHub.

Appendix: source

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

/// 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)
}

fn remote_has_userinfo(url: &str) -> bool {
    if let Ok(parsed) = reqwest::Url::parse(url) {
        return !parsed.username().is_empty() || parsed.password().is_some();

View on GitHub (pinned to 73e0f67d83)