tonhowtf/omniget · error · anyhow::Error

Guest token ausente na resposta

Error message

Guest token ausente na resposta

What it means

Thrown by get_guest_token when Twitter's guest-token activation endpoint responds with 200 but the JSON body has no string field `guest_token`. The function requires that field to cache and return a guest token; anything else (missing key, non-string value) yields None, so this anyhow error is raised.

Solutions

  1. Log the raw response body before parsing to inspect what the activation endpoint actually returned
  2. Ensure the request sends the required headers (e.g. `Authorization: Bearer <web bearer token>`) — without them Twitter may return a 200 body without the token
  3. Check for Twitter API schema changes and update the guest-token activation URL/headers
  4. Add a retry with backoff, since transient anti-bot/CDN responses can omit the token
  5. Upgrade/patch this app if a newer Twitter syndication flow is available

Example fix

// before
let token = json.get("guest_token").and_then(|v| v.as_str()).ok_or_else(|| anyhow!("Guest token ausente na resposta"))?.to_string();
// after
if let Some(token) = json.get("guest_token").and_then(|v| v.as_str()) {
    // use token
} else {
    tracing::warn!("guest activate body: {}", String::from_utf8_lossy(&raw_body));
    return Err(anyhow!("Guest token ausente na resposta"));
}
Defensive patterns

Strategy: validation

Validate before calling

fn looks_like_guest_token_body(v: &serde_json::Value) -> bool {
    v.get("guest_token").and_then(|t| t.as_str()).map(|t| !t.is_empty()).unwrap_or(false)
}

Type guard

fn as_guest_token(v: &serde_json::Value) -> Option<&str> {
    v.get("guest_token").and_then(|t| t.as_str()).filter(|t| !t.is_empty())
}

Try / catch

match get_guest_token().await {
    Ok(t) => use_token(&t),
    Err(e) if e.to_string().contains("ausente") => {
        tracing::warn!("guest token missing from activate response, retrying");
        retry_with_backoff(3).await
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: POST to the guest/activate endpoint succeeds (HTTP 2xx) but the response JSON lacks `guest_token` or it is not a string — e.g. Twitter changed the response shape, a proxy/CDN returned an HTML or compressed body that serde parsed as a JSON object without the key, or an error object was returned with status 200.

Common situations: Twitter silently changes the activation API (no `guest_token` key anymore); transparent corporate proxy or captive portal injecting a 200 HTML page; running behind a region/VPN where Twitter returns an alternative payload; anti-bot challenge returning JSON without the token.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/5be56c1566ac65f1. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/src/platforms/twitter/mod.rs:303

            .header("Authorization", BEARER)
            .header("x-twitter-client-language", "en")
            .header("x-twitter-active-user", "yes")
            .header("Accept-Language", "en")
            .send()
            .await?;

        if !response.status().is_success() {
            return Err(anyhow!(
                "Falha ao obter guest token: HTTP {}",
                response.status()
            ));
        }

        let json: serde_json::Value = response.json().await?;
        let token = json
            .get("guest_token")
            .and_then(|v| v.as_str())
            .ok_or_else(|| anyhow!("Guest token ausente na resposta"))?
            .to_string();

        let mut cached = self.guest_token.lock().await;
        *cached = Some(token.clone());
        Ok(token)
    }

    async fn request_tweet(
        &self,
        tweet_id: &str,
        guest_token: &str,
    ) -> anyhow::Result<serde_json::Value> {
        let variables = serde_json::json!({
            "focalTweetId": tweet_id,
            "with_rux_injections": false,
            "rankingMode": "Relevance",
            "includePromotedContent": true,
            "withCommunity": true,

View on GitHub (pinned to 8600b91f42)