tonhowtf/omniget · error
Resposta GQL sem data
Error message
Resposta GQL sem data
What it means
After a successful HTTP 200 from the GraphQL endpoint, request_gql parses the JSON and requires a top-level "data" object. If the key is absent, the response didn't match Instagram's GQL envelope (e.g. an error JSON, challenge page, or HTML error body served with 200) and this error is thrown.
Solutions
- Log the raw response body on this error to see whether it's a GraphQL errors object, a challenge, or HTML.
- Check for a top-level "errors" array in the JSON and surface it to diagnose bad query variables.
- Retry with a fresh anonymous cookie/headers, since 200-with-challenge usually indicates bot detection.
- Verify the response Content-Type is application/json before parsing; treat HTML bodies as an auth/bot failure instead.
Example fix
// before
let data = json.get("data")
.ok_or_else(|| anyhow!("Resposta GQL sem data"))?;
// after
if let Some(errs) = json.get("errors") {
anyhow::bail!("Instagram GQL errors: {}", errs);
}
let data = json.get("data")
.with_context(|| format!("Resposta GQL sem data; body: {}", serde_json::to_string(&json).unwrap_or_default().chars().take(500).collect::<String>()))?; Defensive patterns
Strategy: try-catch
Validate before calling
// After parsing, before trusting the shape:
let json: serde_json::Value = serde_json::from_str(&body)?;
anyhow::ensure!(json.is_object(), "GQL response is not a JSON object (got HTML/empty body?)");
anyhow::ensure!(json.get("data").map_or(false, |d| d.is_object()), "GQL response missing data object"); Type guard
fn gql_data_field(json: &serde_json::Value) -> Option<&serde_json::Value> {
if json.is_object() && json.get("data")?.is_object() { json.get("data") } else { None }
} Try / catch
match platform.get_media_info(url).await {
Err(e) if e.to_string().contains("Resposta GQL sem data") => {
// log raw body, refresh cookies/headers, retry once — often a soft bot-block
eprintln!("GQL envelope missing; refreshing anon cookie and retrying");
refresh_anon_cookie().await?;
platform.get_media_info(url).await
}
other => other,
} Prevention
- Always log the raw response body when the GQL envelope is missing.
- Check for a top-level "errors" key to catch GraphQL-level failures.
- Validate Content-Type is application/json before parsing.
- Treat 200-but-no-data as bot detection: rotate cookies/headers and slow down.
When it happens
Trigger: request_gql receives HTTP 200 but json.get("data") is None: Instagram returned an error object without "data", a bot-check/challenge response, an HTML page mislabeled as JSON, or an empty body that serde deserialized into a non-object Value.
Common situations: Instagram serving soft-block/challenge JSON instead of media data under 200 status; query variables invalid so GraphQL returns {"errors": [...]} without data; schema changes renaming the response envelope; response actually HTML (Cloudflare/anti-bot) parsed leniently.
Related errors
- Instagram GQL retornou HTTP
- nao achei os arquivos JSON de seguidores no export. No…
- e.to_string()
- escolha pelo menos um arquivo
- e.to_string()
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/fb640fb735244d71.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/platforms/instagram.rs:430
.header("X-CSRFToken", ¶ms.csrf_token)
.header("X-FB-Friendly-Name", "PolarisPostActionLoadPostQueryQuery")
.header("x-asbd-id", "129477")
.header("X-Bloks-Version-Id", ¶ms.bloks_version_id)
.header("Referer", "https://www.instagram.com/")
.header("Cookie", &anon_cookie)
.body(body)
.send()
.await?;
if !response.status().is_success() {
return Err(anyhow!("Instagram GQL retornou HTTP {}", response.status()));
}
let json: serde_json::Value = response.json().await?;
let data = json
.get("data")
.ok_or_else(|| anyhow!("Resposta GQL sem data"))?;
let media = data
.get("xdt_shortcode_media")
.or_else(|| data.get("shortcode_media"));
match media {
Some(m) if !m.is_null() => Ok(m.clone()),
_ => Err(anyhow!("Post not found via GQL")),
}
}
async fn request_embed(&self, post_id: &str) -> anyhow::Result<serde_json::Value> {
let url = format!("https://www.instagram.com/p/{}/embed/captioned/", post_id);
let response = self
.client
.get(&url)
.header(View on GitHub (pinned to 8600b91f42)