Hmbown/CodeWhale · error

invalid header pair ' ', expected name=value

Error message

invalid header pair '{pair}', expected name=value

What it means

parse_http_headers, a validation helper over the raw config string, splits the value on commas and requires each pair to contain '='; this error fires when one pair has no name=value form, meaning the offending header pair in the config value is malformed.

Solutions

  1. Write each header as name=value separated by commas: "Authorization=Bearer x,X-Trace=abc"
  2. Replace colons between header name and value with '='
  3. Quote or pre-encode values containing commas so they are not split into fragments

Example fix

// before
headers="Authorization: Bearer x"

// after
headers="Authorization=Bearer x"
Defensive patterns

Strategy: validation

Validate before calling

fn validate_header_string(raw: &str) -> Result<(), String> {
    for pair in raw.trim().split(',') {
        let pair = pair.trim();
        if pair.is_empty() { continue; }
        if !pair.contains('=') || pair.split('=').next().unwrap().trim().is_empty() {
            return Err(format!("bad header pair: {pair}"));
        }
    }
    Ok(())
}

Type guard

fn is_header_pair(fragment: &str) -> bool {
    match fragment.trim().split_once('=') {
        Some((n, _)) => !n.trim().is_empty(),
        None => false,
    }
}

Try / catch

match result {
    Err(e) if e.to_string().contains("invalid header pair") => {
        eprintln!("format headers as comma-separated name=value, not 'Name: value'");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Passing a header string where some fragment lacks '=', e.g. raw="Authorization: Bearer x" (colon instead of equals) or "Foo=bar,Baz" (trailing bare name), or an unquoted value containing '=' handled correctly but a fragment like "=value" empty-name path next (empty name throws a different error; bare fragment throws this one).

Common situations: Using HTTP-style "Name: value" syntax instead of name=value; forgetting to quote values containing commas so the string splits mid-value; pasting a header block with newlines instead of comma separators.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/e7e27bbd68abd595. Report an issue: GitHub.

Appendix: source

Thrown at crates/config/src/lib.rs:6574

}

fn parse_bool(raw: &str) -> Result<bool> {
    match raw.trim().to_ascii_lowercase().as_str() {
        "1" | "true" | "yes" | "on" | "enabled" => Ok(true),
        "0" | "false" | "no" | "off" | "disabled" => Ok(false),
        _ => bail!("invalid boolean '{raw}'"),
    }
}

fn parse_http_headers(raw: &str) -> Result<BTreeMap<String, String>> {
    let mut headers = BTreeMap::new();
    for pair in raw.trim().split(',') {
        let pair = pair.trim();
        if pair.is_empty() {
            continue;
        }
        let Some((name, value)) = pair.split_once('=') else {
            bail!("invalid header pair '{pair}', expected name=value");
        };
        let name = name.trim();
        let value = value.trim();
        if name.is_empty() {
            bail!("header name cannot be empty");
        }
        if value.is_empty() {
            continue;
        }
        headers.insert(name.to_string(), value.to_string());
    }
    Ok(headers)
}

fn serialize_http_headers(headers: &BTreeMap<String, String>) -> Option<String> {
    if headers.is_empty() {
        return None;
    }

View on GitHub (pinned to 73e0f67d83)