{"record":{"id":"58156d99bfeae780","repo":"tonhowtf/omniget","slug":"post-not-available-graphql-syndication-html-mod","errorCode":null,"errorMessage":"Post not available; graphql='{}'; syndication='{}'; html='{}'","messagePattern":"Post not available; graphql='(.+?)'; syndication='(.+?)'; html='(.+?)'","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/src/platforms/twitter/mod.rs","lineNumber":1015,"sourceCode":"                                        \"Post not available; graphql='{}'; syndication_extract='{}'; html='{}'\",\n                                        graphql_err,\n                                        syndication_extract_err,\n                                        html_err\n                                    ));\n                                }\n                            }\n                        }\n                    },\n                    Err(syndication_err) => {\n                        tracing::warn!(\n                            \"[twitter] syndication lookup failed for tweet_id={}: {}\",\n                            tweet_id,\n                            syndication_err\n                        );\n                        match self.request_html_media(url).await {\n                            Ok(items) => items,\n                            Err(html_err) => {\n                                return Err(anyhow!(\n                                    \"Post not available; graphql='{}'; syndication='{}'; html='{}'\",\n                                    graphql_err,\n                                    syndication_err,\n                                    html_err\n                                ));\n                            }\n                        }\n                    }\n                }\n            }\n        };\n\n        let twitter_media = Self::parse_media_items(&media_items)?;\n\n        Ok(Self::media_info_from_twitter_media(\n            filename_base,\n            twitter_media,\n        ))","sourceCodeStart":997,"sourceCodeEnd":1033,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/src/platforms/twitter/mod.rs#L997-L1033","documentation":"This is the terminal aggregate error of TwitterDownloader::native_get_media_info. After all three fetch strategies fail (the GraphQL API, the syndication endpoint, and the HTML fallback), the error bundles all three failure messages into one anyhow! error. It means the tweet's media could not be retrieved through any available channel.","triggerScenarios":"Calling native_get_media_info (via get_media_info) on a tweet URL when: (1) the GraphQL API rejects or errors (auth tokens invalid, API changes), (2) the syndication endpoint errors or returns no media, and (3) request_html_media also fails (non-2xx HTTP, no photo URLs in HTML, or network error).","commonSituations":"Deleted or protected tweets; tweets whose media is age-restricted or requires login (the auth cookie is absent or expired); X/Twitter API or HTML markup changes breaking the extraction regexes; network/firewall blocking pbs.twimg.com or x.com.","solutions":["Check the three embedded sub-errors (graphql=..., syndication=..., html=...) to identify the root cause — usually all three fail for the same reason.","Ensure a valid auth cookie is available: auth_cookie_string() returned None or an expired cookie, so re-authenticate or refresh cookies.txt.","Verify the tweet URL is a valid, public, non-deleted tweet that actually contains media.","Update the app/extraction logic if X changed its HTML or GraphQL responses.","Retry later on transient network failures, or use a fallback extractor such as yt-dlp."],"exampleFix":"// before: letting all three fail silently into one error\nreturn Err(anyhow!(\"Post not available; graphql='{}'; syndication='{}'; html='{}'\", graphql_err, syndication_err, html_err));\n// after: fail fast with a clearer cause when auth is missing\nif Self::auth_cookie_string().is_none() {\n    return Err(anyhow!(\"Post not available: no auth cookie configured; graphql='{}'; syndication='{}'; html='{}'\", graphql_err, syndication_err, html_err));\n}","handlingStrategy":"try-catch","validationCode":"if !url.contains(\"x.com/\") && !url.contains(\"twitter.com/\") { return Err(anyhow!(\"not a tweet URL\")); }\nif Self::auth_cookie_string().is_none() { println!(\"warning: no auth cookie — twitter extraction may fail\"); }","typeGuard":"fn is_tweet_url(url: &str) -> bool {\n    url.contains(\"x.com/\") || url.contains(\"twitter.com/\")\n}","tryCatchPattern":"match downloader.get_media_info(&tweet_url).await {\n    Ok(info) => use(info),\n    Err(e) if e.to_string().contains(\"Post not available\") => {\n        // read the graphql=/syndication=/html= segments for root cause;\n        // prompt user for auth cookie or fall back to yt-dlp\n    }\n    Err(e) => report(e),\n}","preventionTips":["Keep a valid, unexpired auth cookie configured before calling twitter extraction.","Validate the URL is a public tweet containing media before invoking get_media_info.","Read the three embedded sub-error segments to diagnose root cause quickly.","Keep the app updated — X changes its APIs and HTML frequently.","Have a yt-dlp fallback path wired in for tweets the native strategies miss."],"tags":["network","scraping","twitter","media-extraction","fallback-exhausted"],"backgroundTag":"api-error-response","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"}