tonhowtf/omniget · error
/
Error message
{} / {} What it means
ask_x posts the chat to https://api.x.com/2/grok/add_response.json and, if that fails, retries on https://x.com/i/api/2/grok/add_response.json. When BOTH hosts fail, the two transport errors are joined with " / " into a single error. This indicates the request to X's Grok endpoint failed at the HTTP layer on both mirrors, not that Grok rejected the payload.
Solutions
- Read both halves of the error: the first is the api.x.com failure, the second the x.com/i/api failure — fix the root cause they share.
- Refresh the X session/login (most common cause is 401/403 from stale cookies).
- Check network/proxy connectivity to x.com (curl the endpoint).
- If rate-limited (429), wait and retry with backoff.
- Verify X has not moved the add_response endpoint; update the URL constants if so.
Example fix
// before
// both hosts failing with 403 from expired cookies
Err("request failed: 403 Forbidden / request failed: 403 Forbidden")
// after
// re-login to refresh cookies, then retry
client.require_login()?; // or full re-auth flow before ask_x Defensive patterns
Strategy: retry
Validate before calling
// preflight connectivity to X before issuing the chat request
if reqwest::get("https://x.com").await.is_err() { return Err("no connectivity to x.com"); } Try / catch
match grok::ask(req).await {
Ok(a) => use_answer(a),
Err(e) if e.to_string().contains(" / ") => {
// both mirrors failed; backoff then retry once
tokio::time::sleep(Duration::from_secs(5)).await;
grok::ask(req).await
}
Err(e) => log_error(e),
} Prevention
- Ensure outbound network/proxy access to both api.x.com and x.com
- Refresh session cookies when 401/403 errors appear
- Back off on 429 instead of hammering both mirrors
- Watch for X endpoint moves and update the mirror URLs
When it happens
Trigger: Both post_json_raw calls return Err: network/DNS failure, proxy issues, 401/403/429 responses treated as errors by the client, missing x-client-uuid/Referer headers rejected by X, or X blocking the request (anti-bot).
Common situations: No internet or blocked access to x.com; stale session cookies causing 403 on add_response; X rate limiting Grok requests; corporate proxy blocking api.x.com; X changing endpoint paths so both hosts 404.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Twitch GQL não respondeu depois de 5 tentativas
- o servidor está limitando o acesso
- não consegui buscar
- o Reddit está limitando o acesso
- YouTube não retornou URL
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/92f2820caba0adeb.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/x/grok.rs:334
});
let uuid = uuid::Uuid::new_v4().simple().to_string();
let extra = [
("x-client-uuid", uuid.as_str()),
("Referer", "https://x.com/i/grok"),
];
let resp = match client
.post_json_raw("https://api.x.com/2/grok/add_response.json", &body, &extra)
.await
{
Ok(r) => r,
Err(first) => client
.post_json_raw(
"https://x.com/i/api/2/grok/add_response.json",
&body,
&extra,
)
.await
.map_err(|e| anyhow!("{} / {}", first, e))?,
};
let raw = resp.text().await?;
let mut text = String::new();
let mut citations: Vec<Citation> = Vec::new();
for line in raw.lines() {
let Ok(v) = serde_json::from_str::<Value>(line.trim()) else {
continue;
};
let Some(r) = v.get("result") else { continue };
if let Some(m) = r.get("message").and_then(|m| m.as_str()) {
if r.get("sender")
.and_then(|s| s.as_str())
.map(|s| s != "USER")
.unwrap_or(true)
{
text.push_str(m);
}
}View on GitHub (pinned to 8600b91f42)