tonhowtf/omniget · warning · anyhow::Error

Post privado

Error message

Post privado

What it means

extract_graphql_media raises `Post privado` (private post) when the tweet result's `reason` field equals `Protected`. Twitter explicitly marks the tweet as protected, meaning the account is private and the media cannot be fetched without authenticated, authorized access.

Solutions

  1. Detect `reason: Protected` early and return a clear user-facing error distinguishing it from deleted posts
  2. Inform the user the account is private and media cannot be downloaded without logging in with an authorized account
  3. Add authenticated-access support (session cookies) if private-post access is a requirement
  4. Skip protected tweets gracefully in batch downloads instead of failing the whole job

Example fix

// before
if reason == "Protected" {
    return Err(anyhow!("Post privado"));
}
// after
if reason == "Protected" {
    return Err(PlatformError::PrivatePost(format!("tweet {} é de uma conta privada", tweet_id)));
}
Defensive patterns

Strategy: try-catch

Validate before calling

fn reason_is_protected(json: &serde_json::Value) -> bool {
    json.pointer("/data/threaded_conversation_with_injections_v2/instructions").and_then(|i| i.as_array()).map(|ins| ins.iter().filter_map(|i| i.get("entries")).flat_map(|e| e.as_array().unwrap_or(&vec![]).iter()).any(|e| e.pointer("/content/itemContent/tweet_results/result/reason").and_then(|r| r.as_str()) == Some("Protected"))).unwrap_or(false)).unwrap_or(false)
}

Type guard

fn is_protected_result(result: &serde_json::Value) -> bool {
    result.pointer("/result/reason").or_else(|| result.get("reason")).and_then(|r| r.as_str()) == Some("Protected")
}

Try / catch

match extract_graphql_media(&json, id) {
    Err(e) if e.to_string() == "Post privado" => {
        ui.notify_private_post(id); // distinct UX from deleted/unavailable
        Err(SkipPost)
    }
    other => other,
}

Prevention

When it happens

Trigger: GraphQL tweet result contains tweet_results/result with `reason: "Protected"` — the tweet belongs to a protected (private) account and the guest session has no access.

Common situations: User pastes a link to a tweet from a private account; account was switched to protected after the tweet was posted; user expects public content but the author locked their account.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at src-tauri/src/platforms/twitter/mod.rs:514

            .get("__typename")
            .and_then(|v| v.as_str())
            .unwrap_or("");
        tracing::debug!(
            "[twitter] graphql media typename={} tweet_id={}",
            typename,
            tweet_id
        );

        match typename {
            "TweetUnavailable" | "TweetTombstone" => {
                let reason = tweet_result
                    .pointer("/result/reason")
                    .or_else(|| tweet_result.get("reason"))
                    .and_then(|v| v.as_str())
                    .unwrap_or("");

                if reason == "Protected" {
                    return Err(anyhow!("Post privado"));
                }

                let tombstone_text = tweet_result
                    .pointer("/tombstone/text/text")
                    .and_then(|v| v.as_str())
                    .unwrap_or("");

                tracing::warn!(
                    "[twitter] graphql tombstone tweet_id={} reason='{}' tombstone_text='{}'",
                    tweet_id,
                    reason,
                    tombstone_text
                );

                if reason == "NsfwLoggedOut" || tombstone_text.starts_with("Age-restricted") {
                    return Err(anyhow!("Age-restricted content"));
                }

View on GitHub (pinned to 8600b91f42)