{"record":{"id":"55a4af8a542dfe98","repo":"tonhowtf/omniget","slug":"guest-token-ausente","errorCode":null,"errorMessage":"guest token ausente","messagePattern":"guest token ausente","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/x/client.rs","lineNumber":214,"sourceCode":"        let resp = self\n            .http\n            .post(\"https://api.x.com/1.1/guest/activate.json\")\n            .header(\"Authorization\", BEARER)\n            .header(\"x-twitter-client-language\", \"en\")\n            .header(\"x-twitter-active-user\", \"yes\")\n            .send()\n            .await?;\n        if !resp.status().is_success() {\n            return Err(anyhow!(\n                \"X nao entregou guest token: HTTP {}\",\n                resp.status()\n            ));\n        }\n        let v: Value = resp.json().await?;\n        let tok = v\n            .get(\"guest_token\")\n            .and_then(|t| t.as_str())\n            .ok_or_else(|| anyhow!(\"guest token ausente\"))?\n            .to_string();\n        *g = Some((tok.clone(), Instant::now()));\n        Ok(tok)\n    }\n\n    async fn tx_header(&self, method: &str, path: &str) -> Option<String> {\n        if !self.authed() {\n            return None;\n        }\n        let key = hash_str(self.cookie.as_deref().unwrap_or(\"\"));\n        let mut slot = TXID.lock().await;\n        let fresh = match slot.as_ref() {\n            Some((k, _, at)) => *k == key && at.elapsed() < Duration::from_secs(3600),\n            None => false,\n        };\n        if !fresh {\n            let gen = match TxIdGen::create(&self.http, self.cookie.as_deref()).await {\n                Ok(g) => Some(g),","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/x/client.rs#L196-L232","documentation":"After the guest token request succeeds, the client parses the JSON and extracts the guest_token string field. If the field is missing or not a string, it errors with 'guest token ausente' — X replied but not with the expected token payload shape.","triggerScenarios":"guest_token called via headers/gql_get when X's activation response JSON has no string 'guest_token' field — e.g. an HTML challenge/error page served with 200, or an API schema change.","commonSituations":"X serving a login/challenge page to suspicious IPs with HTTP 200; response is JSON but with different field casing/type; interception by a captive portal returning JSON error bodies.","solutions":["Log in with an account so the guest token path is not needed.","Inspect the actual response body to see what X returned instead of guest_token.","Retry from a different IP / after a delay if X is soft-challenging the client.","Update the parsing code if X renamed/re-typed the field."],"exampleFix":"// before\nlet tok = v.get(\"guest_token\").and_then(|t| t.as_str()).ok_or_else(|| anyhow!(\"guest token ausente\"))?;\n// after\nlet tok = v.get(\"guest_token\")\n    .and_then(|t| t.as_str().map(str::to_owned).or_else(|| t.as_i64().map(|n| n.to_string())))\n    .ok_or_else(|| anyhow!(\"guest token ausente: body={}\", v))?","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"fn extract_guest_token(v: &serde_json::Value) -> Option<String> {\n    v.get(\"guest_token\").and_then(|t| t.as_str().map(str::to_owned).or_else(|| t.as_i64().map(|n| n.to_string())))\n}","tryCatchPattern":"match guest_op().await {\n    Err(e) if e.to_string().contains(\"guest token ausente\") => {\n        log_response_snippet(); // capture what X actually returned\n        fallback_to_authenticated_flow()\n    }\n    other => other,\n}","preventionTips":["Log the raw guest-activation body when parsing fails.","Fall back to authenticated requests when the guest flow is unstable.","Set Accept: application/json to avoid HTML challenge pages.","Keep the parser tolerant to numeric vs string token types."],"tags":["x-api","guest-token","response-parsing","json"],"backgroundTag":"unexpected-response-shape","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}