zeroclaw-labs/zeroclaw · error
LinkedIn get_profile failed ({}): {}
Error message
LinkedIn get_profile failed ({}): {} What it means
Thrown when GET {LINKEDIN_API_BASE}/rest/me returns non-2xx, body included. This is usually the first call made with a newly granted token (used to resolve the member id), so failures here are typically token- or scope-level rather than data-level. The parsed profile fields default to empty strings rather than erroring, so this status check is the main failure point.
Source
Thrown at crates/zeroclaw-tools/src/linkedin_client.rs:501
Ok(EngagementSummary {
likes,
comments,
shares,
})
}
pub async fn get_profile(&self) -> anyhow::Result<ProfileInfo> {
let creds = self.get_credentials().await?;
let url = format!("{}/rest/me", LINKEDIN_API_BASE);
let response = self
.api_request(Method::GET, &url, &creds.access_token, None)
.await?;
let status = response.status();
if !status.is_success() {
let body_text = response.text().await.unwrap_or_default();
anyhow::bail!("LinkedIn get_profile failed ({}): {}", status, body_text);
}
let json: serde_json::Value = response
.json()
.await
.context("Failed to parse get_profile response")?;
let id = json
.get("id")
.and_then(|v| v.as_str())
.unwrap_or_default()
.to_string();
let first_name = json
.get("localizedFirstName")
.and_then(|v| v.as_str())
.unwrap_or_default();
View on GitHub (pinned to 88bb9c8533)
Solutions
- For 401, refresh the access token (ensure a refresh token was stored) or re-run the OAuth flow.
- For 403, add the profile/sign-in product and openid profile scope to the app, then re-authorize.
- Verify client_id/client_secret/access_token all come from the same LinkedIn app.
- Retry once after a short delay if the token was just granted.
Defensive patterns
Strategy: try-catch
Try / catch
match client.get_profile().await {
Ok(p) => Ok(p),
Err(e) if e.to_string().contains("(401") => {
// force token refresh, then one retry; if refresh token absent, start OAuth flow
Err(e).context("LinkedIn session expired; re-auth required")
}
Err(e) => Err(e),
} Prevention
- Call get_profile once right after OAuth to validate scopes/tokens before doing real work.
- Store refresh_token at grant time so silent renewal is possible.
- Keep client_id/secret/access/refresh tokens from the same app in one credential record.
When it happens
Trigger: Expired access token with no refresh token available (401); token granted without the profile/openid scope (403); app missing the Sign In with LinkedIn product; calling immediately after grant before propagation.
Common situations: OAuth integrations where only w_member_social was requested; tokens past their lifetime in long-running daemons; developer apps that never added the sign-in product; environment with the wrong client_id/secret pair so the token is invalid.
Related errors
- LinkedIn token refresh failed ({}): {}
- token refresh failed ({status}): {body}
- Google device code request failed ({}): {}
- OpenAI Codex auth profile is not OAuth-based: {profile_id}
- OpenAI Codex auth profile is missing token set: {profile_id}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/46d861e6d895ba2c.
Report an issue: GitHub.