{"record":{"id":"776c1ae524b2b9f0","repo":"tonhowtf/omniget","slug":"could-not-extract-post-data-from-threads-page-the-post-may","errorCode":null,"errorMessage":"Could not extract post data from Threads page. The post may be private or deleted.","messagePattern":"Could not extract post data from Threads page\\. The post may be private or deleted\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/platforms/threads.rs","lineNumber":100,"sourceCode":"        None\n    }\n\n    /// Fetch della pagina e estrazione del post dal JSON bootstrap\n    async fn fetch_post(&self, url: &str, post_id: &str) -> anyhow::Result<serde_json::Value> {\n        let html = self.fetch_page(url, USER_AGENT).await?;\n        if let Some(post) = Self::find_post_in_html(&html, post_id) {\n            return Ok(post);\n        }\n\n        // Alcune richieste anonime vengono murate dal login; col UA crawler\n        // Threads serve la pagina completa\n        tracing::debug!(\"[threads] post not found with browser UA, retrying with crawler UA\");\n        let html = self.fetch_page(url, GOOGLEBOT_UA).await?;\n        if let Some(post) = Self::find_post_in_html(&html, post_id) {\n            return Ok(post);\n        }\n\n        Err(anyhow!(\n            \"Could not extract post data from Threads page. The post may be private or deleted.\"\n        ))\n    }\n\n    async fn fetch_page(&self, url: &str, user_agent: &str) -> anyhow::Result<String> {\n        let response = self\n            .client\n            .get(url)\n            .header(\"User-Agent\", user_agent)\n            .header(\n                \"Accept\",\n                \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n            )\n            .header(\"Accept-Language\", \"en-GB,en;q=0.9\")\n            .header(\"Sec-Fetch-Dest\", \"document\")\n            .header(\"Sec-Fetch-Mode\", \"navigate\")\n            .header(\"Sec-Fetch-Site\", \"none\")\n            .header(\"Sec-Fetch-User\", \"?1\")","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/platforms/threads.rs#L82-L118","documentation":"fetch_post in threads.rs tries to locate the post's bootstrap JSON in the fetched page HTML, first with a browser UA and then with a crawler (Googlebot) UA. If find_post_in_html fails on both attempts it gives up with this error, meaning Threads returned a page but the post data could not be extracted — typically because the post is private, deleted, geo-blocked, or Threads changed its page markup.","triggerScenarios":"get_media_info -> fetch_post on a Threads URL where: (1) the post ID is valid but the post was deleted or made private, (2) the <script data-sjs> markup no longer contains the post (Threads frontend changed), (3) the page served was a login/consent wall for both user agents.","commonSituations":"Sharing links to deleted/private Threads posts; Threads A/B-testing new page structure that breaks find_post_in_html; region-locked content returning an empty shell page.","solutions":["Verify the post is publicly viewable in a browser (not deleted/private)","Confirm the URL contains a valid post ID and re-test","Update find_post_in_html parsing for new Threads page markup if the platform changed","Treat this as terminal in the UI: tell the user the post is unavailable rather than retrying"],"exampleFix":"null","handlingStrategy":"retry","validationCode":"if (!/^https:\\/\\/(www\\.)?threads\\.((com)|(net))\\/@[\\w.]+\\/post\\/[\\w-]+/.test(url)) {\n  throw new Error(\"URL is not a Threads post URL\");\n}","typeGuard":null,"tryCatchPattern":"match threads.get_media_info(url).await {\n    Err(e) if e.to_string().contains(\"may be private or deleted\") => {\n        // terminal: do not retry\n        inform_user(\"Post is private or deleted\");\n    }\n    other => other?,\n}","preventionTips":["Verify the post renders publicly in a browser before automating","Pin/monitor Threads page markup changes that break find_post_in_html","Distinguish private/deleted from parse failures in your own error mapping","Keep browser UA and crawler UA fallback paths current"],"tags":["threads","scraping","post-not-found"],"backgroundTag":"resource-not-found","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}