zeroclaw-labs/zeroclaw · critical

valid api version header

Error message

valid api version header

What it means

The same header-safety invariant applied to the `LinkedIn-Version` header. `api_version` is a free String injected through `LinkedInClient::new`; if it contains spaces, newlines, or non-ASCII bytes, `HeaderValue::from_str` fails and `.expect()` panics before the request is sent.

Source

Thrown at crates/zeroclaw-tools/src/linkedin_client.rs:176

    fn client() -> reqwest::Client {
        zeroclaw_config::schema::build_runtime_proxy_client_with_timeouts(
            "tool.linkedin",
            LINKEDIN_REQUEST_TIMEOUT_SECS,
            LINKEDIN_CONNECT_TIMEOUT_SECS,
        )
    }

    fn api_headers(&self, token: &str) -> HeaderMap {
        let mut headers = HeaderMap::new();
        let bearer = format!("Bearer {}", token);
        headers.insert(
            reqwest::header::AUTHORIZATION,
            HeaderValue::from_str(&bearer).expect("valid bearer token header"),
        );
        headers.insert(
            "LinkedIn-Version",
            HeaderValue::from_str(&self.api_version).expect("valid api version header"),
        );
        headers.insert(
            "X-Restli-Protocol-Version",
            HeaderValue::from_static("2.0.0"),
        );
        headers
    }

    async fn api_request(
        &self,
        method: Method,
        url: &str,
        token: &str,
        body: Option<serde_json::Value>,
    ) -> anyhow::Result<reqwest::Response> {
        let client = Self::client();
        let headers = self.api_headers(token);

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Set api_version to the strict `YYYY-MM` form LinkedIn expects (e.g. `2025-01`)
  2. Trim and shape-check the configured version where the tool config is parsed
  3. Reject malformed versions at config load with a validation error instead of panicking at request time

Example fix

// before
let ver = self.api_version.clone(); // "2025-01\n"
HeaderValue::from_str(&ver).expect("valid api version header"),

// after
let ver = self.api_version.trim().to_string();
HeaderValue::from_str(&ver).expect("valid api version header"),
Defensive patterns

Strategy: validation

Validate before calling

let ver = config_value.trim();
assert!(is_valid_linkedin_api_version(ver), "api_version must be YYYY-MM");

Type guard

fn is_valid_linkedin_api_version(v: &str) -> bool {
    let b = v.as_bytes();
    v.len() == 7
        && b[4] == b'-'
        && b[..4].iter().all(|c| c.is_ascii_digit())
        && b[5..].iter().all(|c| c.is_ascii_digit())
}

Prevention

When it happens

Trigger: The linkedin tool is configured with an api_version like `"2025-01 beta"`, one with a trailing newline, or any non-ASCII variant; the next API call builds headers and panics.

Common situations: Hand-edited tool config; copy-paste of version strings from docs or webpages carrying formatting; config generated from templates with untrimmed fields.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/7eca97917e13fac3. Report an issue: GitHub.