tonhowtf/omniget · error

resposta nao e JSON

Error message

resposta nao e JSON: {}

What it means

After a successful HTTP status, models() parses the response body with serde_json::from_str; if the body is not valid JSON it throws this error with the first 120 characters of the body. This happens when an endpoint returns HTML (login page, error page, Cloudflare challenge) or plain text instead of the expected JSON model list.

Solutions

  1. Inspect the 120-char body snippet in the error: HTML tags mean the URL points at a web page, not the API; fix base_url to the correct API route (e.g. /v1/models).
  2. Verify the endpoint returns JSON with curl (curl -H 'Authorization: Bearer KEY' <base>/models).
  3. Check for proxies/VPNs or network middleboxes returning HTML challenge pages.
  4. Confirm the provider is an OpenAI-compatible API and not a plain website panel.

Example fix

// before
base_url = "https://panel.example.com"          // serves HTML
// after
base_url = "https://panel.example.com/v1"       // API route returns JSON
Defensive patterns

Strategy: validation

Validate before calling

let text = resp.text().await?;
if text.trim_start().parse::<serde_json::Value>().is_err() {
    eprintln!("endpoint did not return JSON — check base_url points at the API, not the website");
}
let v: serde_json::Value = serde_json::from_str(&text)?;

Type guard

fn looks_like_json(body: &str) -> bool {
    let t = body.trim_start();
    t.starts_with('{') || t.starts_with('[')
}

Try / catch

match models(id).await {
    Ok(list) => use(list),
    Err(e) if e.to_string().starts_with("resposta nao e JSON") => {
        // body snippet is in the message; fix base_url or inspect for HTML/Cloudflare pages
        show_misconfigured_url_hint(&e.to_string());
    }
    Err(e) => show_error(e),
}

Prevention

When it happens

Trigger: Provider endpoint returns 200 but with non-JSON body: HTML login/Cloudflare page, empty body, or plain-text error; base_url pointing at a website rather than an API route.

Common situations: base_url misconfigured to the dashboard URL so the server returns the HTML SPA; a proxy/captive portal intercepting requests; provider API returning empty body on some error paths; custom/new-api compatible panels returning HTML for unknown routes.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/3d017e765d08b696. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/ai_keys.rs:363

            .await?
        }
        _ => {
            let mut req = c.get(format!("{}/models", entry.base_url));
            if !entry.key.is_empty() {
                req = req.bearer_auth(&entry.key);
            }
            let resp = req.send().await?;
            let status = resp.status();
            let text = resp.text().await.unwrap_or_default();
            if !status.is_success() {
                return Err(anyhow!(
                    "HTTP {}: {}",
                    status.as_u16(),
                    text.chars().take(200).collect::<String>()
                ));
            }
            serde_json::from_str(&text).map_err(|_| {
                anyhow!(
                    "resposta nao e JSON: {}",
                    text.chars().take(120).collect::<String>()
                )
            })?
        }
    };
    let arr = json
        .get("data")
        .or_else(|| json.get("models"))
        .and_then(|v| v.as_array())
        .cloned()
        .unwrap_or_default();
    let mut ids: Vec<String> = arr
        .iter()
        .filter_map(|m| {
            m.get("id")
                .or_else(|| m.get("name"))
                .and_then(|v| v.as_str())

View on GitHub (pinned to 8600b91f42)