Hmbown/CodeWhale · warning

Pass a host like `github.com`, not a URL path

Error message

Pass a host like `github.com`, not a URL path

What it means

normalize_host_arg rejects inputs that look like a URL path rather than a bare host. If the input contains `://` (not a plain http/https prefix that can be salvaged) or a `/`, it bails telling the user to pass a hostname like `github.com`. The rules operate on hostnames, not full URLs or paths.

Solutions

  1. Pass only the hostname: `github.com`, not `https://github.com/org/repo`
  2. If you have an http(s) URL, the command extracts its host automatically; strip other schemes manually
  3. Use a wildcard host (e.g. `*.example.com`) instead of URL paths for subpath rules

Example fix

// before
/network allow https://github.com/org/repo
// after
/network allow github.com
Defensive patterns

Strategy: validation

Validate before calling

function isBareHost(s) {
  const t = s.trim();
  if (t.includes('/') || /\w+:\/\//.test(t)) return false;
  return t.length > 0;
}
if (!isBareHost(arg)) throw new Error('Pass a host like `github.com`');

Type guard

const isBareHost = (s: string): boolean => {
  const t = s.trim();
  return t.length > 0 && !t.includes('/') && !t.includes('://');
};

Try / catch

try { run('/network allow ' + arg); } catch (e) { if (String(e).includes('URL path')) arg = new URL(arg).host; }

Prevention

When it happens

Trigger: `/network allow ftp://example.com`, `/network allow github.com/org/repo`, or any argument containing a `/` without an http(s) scheme prefix.

Common situations: Pasting a full repository URL or an API endpoint path instead of the hostname; using non-http schemes like ftp:// or ws:// which are not auto-parsed.

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/36932165b25bfec2. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/commands/groups/utility/network.rs:277

    if !list
        .iter()
        .any(|existing| normalize_host_for_compare(existing) == host)
    {
        list.push(host.to_string());
    }
}

fn remove_host(list: &mut Vec<String>, host: &str) {
    list.retain(|existing| normalize_host_for_compare(existing) != host);
}

fn normalize_host_arg(input: &str) -> anyhow::Result<String> {
    let trimmed = input.trim();
    let host = if trimmed.starts_with("http://") || trimmed.starts_with("https://") {
        host_from_url(trimmed).context("URL must include a host")?
    } else {
        if trimmed.contains("://") || trimmed.contains('/') {
            bail!("Pass a host like `github.com`, not a URL path");
        }
        trimmed.to_string()
    };

    let normalized = normalize_host_for_compare(&host);
    if normalized.is_empty() {
        bail!("host cannot be empty");
    }
    Ok(normalized)
}

/// Extract the host portion of a URL, lowercased (leaf `reqwest::Url` parse;
/// no TUI helper dependency).
fn host_from_url(url: &str) -> Option<String> {
    let parsed = reqwest::Url::parse(url.trim()).ok()?;
    parsed.host_str().map(str::to_ascii_lowercase)
}

View on GitHub (pinned to 73e0f67d83)