{"record":{"id":"0667c4fdb4bdda8a","repo":"tonhowtf/omniget","slug":"post-not-available-graphql-syndication-extract-html","errorCode":null,"errorMessage":"Post not available; graphql='{}'; syndication_extract='{}'; html='{}'","messagePattern":"Post not available; graphql='(.+?)'; syndication_extract='(.+?)'; html='(.+?)'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/platforms/twitter.rs","lineNumber":929,"sourceCode":"            Err(graphql_err) => {\n                tracing::warn!(\n                    \"[twitter] graphql lookup failed for tweet_id={}: {}\",\n                    tweet_id,\n                    graphql_err\n                );\n                match self.request_syndication(&tweet_id).await {\n                    Ok(syndication) => match Self::extract_syndication_media(&syndication) {\n                        Ok(items) => items,\n                        Err(syndication_extract_err) => {\n                            tracing::warn!(\n                                \"[twitter] syndication media extraction failed for tweet_id={}: {}\",\n                                tweet_id,\n                                syndication_extract_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_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) => {","sourceCodeStart":911,"sourceCodeEnd":947,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/platforms/twitter.rs#L911-L947","documentation":"In native_get_media_info, when the GraphQL lookup fails, the syndication endpoint succeeds but extract_syndication_media cannot pull media out of its payload, and the final HTML-scrape fallback (request_html_media) also fails, the library aggregates all three failures into this single error. It means every extraction channel for the tweet was exhausted without finding media.","triggerScenarios":"try_graphql fails (guest token/HTTP error), request_syndication returns JSON whose extraction errors (unexpected/empty syndication payload), and request_html_media fails (non-2xx HTML response or no photo URLs found in HTML) — all for the same tweet_id.","commonSituations":"Deleted, protected, or age-restricted/sensitive-media posts; Twitter rate-limiting or blocking guest tokens and anonymous HTML requests; cookie missing so sensitive media is hidden; syndication API schema change breaking extract_syndication_media while GraphQL is also down (e.g. token endpoint blocked in some regions); bot-detection on anonymous requests.","solutions":["Check the tweet in a browser — if it's deleted, protected, or age-gated, both extraction paths will legitimately fail.","Configure the X/Twitter auth cookie so request_html_media (and downstream yt-dlp) can see restricted media.","Read the three embedded sub-errors: fix the GraphQL/syndication root causes (guest token fetching, schema drift in extract_syndication_media).","Retry after a delay if the embedded errors suggest rate limiting or transient 4xx/5xx responses.","If syndication_extract indicates a parsing error, update extract_syndication_media for the current syndication API JSON shape."],"exampleFix":"// before: calling with no credentials for a sensitive post\nlet info = downloader.get_media_info(url).await?;\n// after: supply auth cookie and retry once on aggregate failure\nset_twitter_cookie(env::var(\"X_AUTH_COOKIE\")?);\nlet info = match downloader.get_media_info(url).await {\n    Ok(i) => i,\n    Err(e) if e.to_string().contains(\"Post not available\") => {\n        tokio::time::sleep(Duration::from_secs(5)).await;\n        downloader.get_media_info(url).await?\n    }\n    Err(e) => return Err(e),\n};","handlingStrategy":"fallback","validationCode":"// Confirm accessibility expectations before calling: permalink + cookie configured\nfn precheck(url: &str, has_cookie: bool) -> Result<(), String> {\n    if !url.contains(\"/status/\") { return Err(\"not a permalink\".into()); }\n    if !has_cookie { println!(\"warning: sensitive/age-restricted posts will fail without an X cookie\"); }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"match downloader.get_media_info(url).await {\n    Err(e) if e.to_string().contains(\"Post not available\") => {\n        // all three channels failed; check embedded graphql/syndication/html causes\n        eprintln!(\"tweet unavailable via all channels: {e}\");\n        // surface a user-facing 'post deleted or private' message\n    }\n    other => other?,\n}","preventionTips":["Configure the X/Twitter auth cookie — the single biggest guard for restricted/sensitive media.","Detect deleted/protected posts upstream and skip extraction instead of calling.","Respect guest-token rate limits; add backoff before retrying.","Keep extract_syndication_media updated against the live syndication API schema.","Fall back to yt-dlp via the outer get_media_info path rather than calling native-only internals."],"tags":["twitter","scraping","fallback-exhausted","media-extraction"],"backgroundTag":"entity-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"}