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

  1. 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.
  2. Refresh the X session/login (most common cause is 401/403 from stale cookies).
  3. Check network/proxy connectivity to x.com (curl the endpoint).
  4. If rate-limited (429), wait and retry with backoff.
  5. 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

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


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)