zeroclaw-labs/zeroclaw · critical
valid bearer token header
Error message
valid bearer token header
What it means
`api_headers` formats `Bearer {token}` into an HTTP header value. `HeaderValue::from_str` rejects any byte outside visible ASCII (0x21-0x7E plus space and tab) — newlines, control characters, non-ASCII. The `.expect()` assumes the stored LinkedIn token is header-safe, so a token containing whitespace, quotes, or a trailing newline aborts the process before a request is sent.
Source
Thrown at crates/zeroclaw-tools/src/linkedin_client.rs:172
refresh_token,
person_id,
})
}
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>,View on GitHub (pinned to 88bb9c8533)
Solutions
- Trim the token where it is loaded: pass `token.trim()` into the client
- Fix the stored credential — remove quotes, whitespace, and newlines in the env var, auth store, or config entry
- Validate the token is header-safe ASCII before invoking the LinkedIn tool (see guard below)
Example fix
// before
let bearer = format!("Bearer {}", token); // token has a trailing newline
HeaderValue::from_str(&bearer).expect("valid bearer token header"),
// after
let bearer = format!("Bearer {}", token.trim());
HeaderValue::from_str(&bearer).expect("valid bearer token header"), Defensive patterns
Strategy: validation
Validate before calling
fn ensure_header_safe(token: &str) -> Result<&str, String> {
let t = token.trim();
if t.is_empty() || !t.bytes().all(|b| (0x21..=0x7e).contains(&b)) {
return Err("token contains non header-safe characters".into());
}
Ok(t)
} Type guard
fn is_valid_bearer_token(token: &str) -> bool {
let t = token.trim();
!t.is_empty() && t.bytes().all(|b| (0x21..=0x7e).contains(&b))
} Try / catch
// only when credentials are untrusted and panic=unwind is set:
let outcome = std::panic::catch_unwind(|| client.api_request(/* ... */));
if outcome.is_err() {
// treat as a malformed credential: trim/replace the token and retry once
} Prevention
- Trim tokens when reading them from env vars, files, or secrets managers
- Never store tokens with surrounding quotes or whitespace
- Add a startup auth check that validates credential shape before serving traffic
When it happens
Trigger: Any LinkedIn API call that builds headers (`api_request`, `api_headers`) with a token containing invalid header bytes: a trailing `\n` from a file read, surrounding quotes from a paste, or a non-ASCII character inside the token string.
Common situations: `$(cat token.txt)` shell capture appending a newline; `.env` values pasted with quotes; secrets-manager entries with trailing whitespace; tokens copied from a web UI with zero-width characters.
Related errors
- valid api version 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/7ff0bcc2b84c0fca.
Report an issue: GitHub.