{"record":{"id":"cc485f6fa2ec2a05","repo":"tonhowtf/omniget","slug":"x-http-sessao-expirada-entre-de-novo-no-x","errorCode":null,"errorMessage":"X {}: HTTP {} (sessao expirada? entre de novo no X)","messagePattern":"X (.+?): HTTP (.+?) \\(sessao expirada\\? entre de novo no X\\)","errorType":"exception","errorClass":null,"httpStatus":401,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/x/client.rs","lineNumber":392,"sourceCode":"            }\n            let headers = self.headers(\"GET\", &path).await?;\n            let resp = self\n                .http\n                .get(&url)\n                .headers(headers)\n                .query(&query)\n                .send()\n                .await?;\n            match Self::check(resp, op).await? {\n                Ok(v) => return Ok(v),\n                Err(kind) if tries < 3 => {\n                    if kind == \"not_found\" {\n                        tracing::info!(\"[x] {} 404: recarregando query ids\", op);\n                        self.refresh_ids().await?;\n                    } else if !self.authed() {\n                        self.guest_token(true).await?;\n                    } else {\n                        return Err(anyhow!(\n                            \"X {}: HTTP {} (sessao expirada? entre de novo no X)\",\n                            op,\n                            kind.trim_start_matches(\"auth:\")\n                        ));\n                    }\n                }\n                Err(kind) => return Err(anyhow!(\"X {}: {}\", op, kind)),\n            }\n        }\n    }\n\n    pub async fn gql_post(\n        &self,\n        op: &str,\n        variables: Value,\n        features: Option<Value>,\n    ) -> anyhow::Result<Value> {\n        self.require_login()?;","sourceCodeStart":374,"sourceCodeEnd":410,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/x/client.rs#L374-L410","documentation":"After retries, gql_get got an HTTP 401/403 (kind \"auth:<status>\") while the client considered itself logged in (cookies present), so it reports that the X session is expired and asks the user to log in again. The message interpolates the trimmed status code (401 or 403).","triggerScenarios":"Stored X cookies (auth_token/ct0) are stale, revoked, or the ct0 csrf header no longer matches the session; server responds 401/403 to a gql_get op and the guest-token fallback is not used because authed() is true.","commonSituations":"User changed password or logged out elsewhere, cookies copied from a browser session that later expired, clock drift invalidating csrf, or X rotating ct0 so the cached header mismatches.","solutions":["Re-authenticate with X: delete the stored cookie jar and log in again so fresh auth_token/ct0 are captured","Clear ct0 and let the client refresh it; ensure the x-csrf-token header matches the current ct0 cookie","Check that cookies were not truncated/corrupted in storage (re-import from the browser)","If this happens for one op only, confirm that op is allowed for your account (some endpoints 403 without Premium/permissions)","Handle the error in callers by surfacing a 're-login' prompt rather than retrying endlessly"],"exampleFix":"// before\nmatch client.gql_get(\"UserTweets\", v, f, None).await {\n    Err(e) if e.to_string().contains(\"sessao expirada\") => prompt_relogin()?;\n    r => r?,\n}\n// after\nif !client.authed() || cookies_expired()? {\n    prompt_relogin()?; // refresh auth_token + ct0 before any gql call\n}\nlet v = client.gql_get(\"UserTweets\", v, f, None).await?;","handlingStrategy":"try-catch","validationCode":"// Rust: verify a session exists before GraphQL calls\nif !client.authed() {\n    return Err(anyhow!(\"not logged in to X; re-login required\"));\n}","typeGuard":null,"tryCatchPattern":"match client.gql_get(op, vars, feats, None).await {\n    Err(e) if e.to_string().contains(\"sessao expirada\") => {\n        relogin()?; // fresh auth_token + ct0\n        client.gql_get(op, vars, feats, None).await\n    }\n    r => r,\n}","preventionTips":["Re-import cookies after any password change or logout on the device","Check cookie freshness (age) before long jobs and re-login proactively","Keep ct0 and the x-csrf-token header in sync","Do not run unattended jobs on sessions older than a few days without a health check"],"tags":["x","authentication","session-expired","cookies"],"backgroundTag":"jwt-token-expired","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}