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
- Log the raw response body before parsing to inspect what the activation endpoint actually returned
- 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
- Check for Twitter API schema changes and update the guest-token activation URL/headers
- Add a retry with backoff, since transient anti-bot/CDN responses can omit the token
- 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
- Send the full required header set (bearer token, user-agent) on the activate call
- Log raw response bodies at debug level to catch schema changes early
- Validate the parsed JSON shape before using it
- Refresh the guest token proactively before long batch jobs
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
- YouTube não retornou URL
- token_expired
- X nao entregou guest token: HTTP
- Falha ao obter guest token: HTTP
- Twitter API retornou HTTP
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)