tonhowtf/omniget · error
resposta inesperada do Reddit (não é a lista de dois…
Error message
resposta inesperada do Reddit (não é a lista de dois listings)
What it means
`parse_thread_json` expects Reddit's permalink response to be a JSON array of exactly two listings (post listing, then comments listing). This error is thrown when the root JSON value is not an array at all — meaning the response body did not have the documented shape.
Solutions
- Log/inspect the raw response body before parsing to confirm it is the expected `[listing, listing]` array
- Check whether the request was redirected to a blocked/login page and handle that case before parsing
- Validate the response with a shape check (root.is_array() && root.len() >= 2) before calling parse_thread_json
- Update the parser if Reddit changed its permalink response structure
Example fix
// before
let (post, comments, mores) = parse_thread_json(&root)?;
// after
if !root.is_array() || root.as_array().map_or(true, |a| a.len() < 2) {
anyhow::bail!("corpo inesperado: {}", serde_json::to_string(&root).unwrap_or_default());
}
let (post, comments, mores) = parse_thread_json(&root)?; Defensive patterns
Strategy: type-guard
Validate before calling
fn looks_like_thread_json(root: &serde_json::Value) -> bool {
root.as_array().map_or(false, |a| a.len() >= 2)
} Type guard
fn is_two_listings(v: &Value) -> bool {
v.is_array() && v.as_array().unwrap().len() >= 2
&& v[0].pointer("/data/children").is_some()
} Try / catch
match parse_thread_json(&root) {
Ok((post, comments, mores)) => /* ... */,
Err(e) if e.to_string().contains("resposta inesperada") => {
eprintln!("formato de resposta não reconhecido; salve o corpo bruto p/ debug");
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Log the raw response body whenever parsing fails so shape changes are visible
- Pre-check root.is_array() and length >= 2 before parsing
- Pin/refresh fixtures used with thread_from_fixture against the live API
- Detect HTML/block-page responses before handing them to the parser
When it happens
Trigger: Calling parse_thread_json (via expand, run, thread_from_fixture, or separa_os_dois_tipos_de_more) with a root Value that is an object, string, or null instead of the `[post, comments]` array — e.g. Reddit returned an HTML error page parsed loosely, an error JSON object, or a malformed fixture.
Common situations: Reddit serving an interstitial/error JSON (e.g. blocked message) instead of thread data; passing the wrong file to thread_from_fixture; Reddit API shape changes; HTML login/blocked pages being fed to the parser.
Related errors
- o post não veio na resposta (removido, privado ou apagado?)
- Expected a JSON array of cookie objects.
- o Reddit respondeu algo que não é JSON
- o JSON do yt-dlp não foi lido
- a saída do gallery-dl não é um dump JSON válido
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/4820bbf3af9e3b32.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/reddit/thread.rs:193
.unwrap_or_default();
let parent_id = s(data, "parent_id");
if !parent_id.is_empty() {
mores.push(MoreRef {
parent_id,
children,
});
}
}
_ => {}
}
}
}
/// A resposta de um permalink é `[listing do post, listing dos comentários]`.
pub fn parse_thread_json(root: &Value) -> Result<(Post, Vec<Comment>, Vec<MoreRef>)> {
let arr = root
.as_array()
.ok_or_else(|| anyhow!("resposta inesperada do Reddit (não é a lista de dois listings)"))?;
let post_data = arr
.first()
.and_then(|l| l.pointer("/data/children/0/data"))
.ok_or_else(|| anyhow!("o post não veio na resposta (removido, privado ou apagado?)"))?;
let post = parse_post(post_data);
let mut flat = Vec::new();
let mut mores = Vec::new();
if let Some(children) = arr.get(1).and_then(|l| l.pointer("/data/children")) {
parse_things(children, &mut flat, &mut mores);
}
Ok((post, flat, mores))
}
/// O `things` de `api/morechildren.json`.
pub fn parse_more_json(root: &Value) -> (Vec<Comment>, Vec<MoreRef>) {
let mut flat = Vec::new();
let mut mores = Vec::new();
if let Some(things) = rootView on GitHub (pinned to 8600b91f42)