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

  1. For 401, refresh the access token (ensure a refresh token was stored) or re-run the OAuth flow.
  2. For 403, add the profile/sign-in product and openid profile scope to the app, then re-authorize.
  3. Verify client_id/client_secret/access_token all come from the same LinkedIn app.
  4. 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

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


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