tonhowtf/omniget · error

post indisponivel

Error message

post indisponivel

What it means

unroll_graphql collects posts from an X (Twitter) GraphQL thread, deduplicates them, and then looks up the focal post by its ID. If the requested post ID is not present in the fetched thread data, it throws "post indisponivel". This means the thread was reachable but the specific post could not be located among its replies/ancestors.

Solutions

  1. Verify the tweet ID extracted from the URL actually exists (open the URL in a browser) and retry with a fresh request.
  2. Check if the tweet is deleted, protected, or age-restricted; use an authenticated session if available.
  3. Inspect the raw GraphQL response to see whether parsing dropped entries (response-shape change) and update the parser.
  4. Retry on transient failures — a partial GraphQL response can omit the focal post.

Example fix

// before
let focal = all.iter().find(|p| p.id == id).cloned().ok_or_else(|| anyhow!("post indisponivel"))?;
// after
let focal = match all.iter().find(|p| p.id == id) {
    Some(p) => p.clone(),
    None => return Err(anyhow!("post {} indisponivel (thread continha {} posts)", id, all.len())),
};
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust
if tweet_id.is_empty() || !tweet_id.chars().all(|c| c.is_ascii_digit()) {
    return Err(anyhow!("ID de tweet inválido antes de unroll"));
}

Type guard

fn has_focal_post(all: &[XPost], id: &str) -> bool {
    all.iter().any(|p| p.id == id)
}

Try / catch

match unroll(url).await {
    Ok(thread) => use(thread),
    Err(e) if e.to_string().contains("post indisponivel") => {
        eprintln!("post removido ou thread parcial; verifique a URL no navegador");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling unroll on an X thread whose GraphQL response does not contain a post matching the requested id — e.g. the tweet was deleted, the ID belongs to a different conversation, the API response was truncated, or the conversation module filtered it out.

Common situations: Deleted or protected tweets; URLs where the status ID is a redirect target that no longer exists; X changing GraphQL response shapes so thread entries are dropped during parsing; rate-limited/partial GraphQL responses.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/x/thread.rs:95

            vars["cursor"] = json!(c);
        }
        let v = client
            .gql_get("TweetDetail", vars, json!({}), Some(json!({"withArticleRichContentState": true, "withArticlePlainText": false, "withGrokAnalyze": false, "withDisallowedReplyControls": false})))
            .await?;
        all.extend(super::parse::tweets_from(&v));
        // cursores de "mostrar mais desta conversa"
        let next = find_show_more(&v);
        if next.is_none() || Some(&next.clone().unwrap()) == cursor.as_ref() {
            break;
        }
        cursor = next;
    }
    let all = super::dedup_posts(all);
    let focal = all
        .iter()
        .find(|p| p.id == id)
        .cloned()
        .ok_or_else(|| anyhow!("post indisponivel"))?;
    let author = focal.author.handle.to_ascii_lowercase();
    let mut by_id: std::collections::HashMap<String, XPost> = all
        .iter()
        .filter(|p| p.author.handle.to_ascii_lowercase() == author)
        .map(|p| (p.id.clone(), p.clone()))
        .collect();
    // sobe ate a raiz
    let mut root = focal.clone();
    while let Some(parent) = root
        .reply_to_id
        .clone()
        .and_then(|pid| by_id.get(&pid).cloned())
    {
        root = parent;
    }
    // desce pela cadeia de respostas do autor
    let mut chain = vec![root.clone()];
    by_id.remove(&root.id);

View on GitHub (pinned to 8600b91f42)