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
- Set api_version to the strict `YYYY-MM` form LinkedIn expects (e.g. `2025-01`)
- Trim and shape-check the configured version where the tool config is parsed
- 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
- Keep api_version in strict YYYY-MM form sourced from LinkedIn's API docs
- Validate tool config strings at load time instead of relying on request-time panics
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
- valid bearer token header
- purge_agent not supported by this memory backend
- rename_agent not supported by this memory backend
- memory backend '{}' does not support StoreOptions kind/pinne
- memory backend '{}' does not support agent-attributed StoreO
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/7eca97917e13fac3.
Report an issue: GitHub.