{"record":{"id":"3921d6f6fa6fc1e4","repo":"tonhowtf/omniget","slug":"post-not-available-3921d6","errorCode":null,"errorMessage":"Post not available","messagePattern":"Post not available","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/src/platforms/tiktok/mod.rs","lineNumber":206,"sourceCode":"                return Err(anyhow!(\"Post not available (status {})\", status_code));\n            }\n        }\n\n        let detail = video_detail\n            .pointer(\"/itemInfo/itemStruct\")\n            .ok_or_else(|| anyhow!(\"Video data not found in TikTok response\"))?\n            .clone();\n\n        if detail\n            .get(\"isContentClassified\")\n            .and_then(|v| v.as_bool())\n            .unwrap_or(false)\n        {\n            return Err(anyhow!(\"Age-restricted content\"));\n        }\n\n        if detail.get(\"author\").is_none() {\n            return Err(anyhow!(\"Post not available\"));\n        }\n\n        Ok(detail)\n    }\n\n    fn extract_author(detail: &serde_json::Value) -> String {\n        detail\n            .pointer(\"/author/uniqueId\")\n            .or_else(|| detail.pointer(\"/author/unique_id\"))\n            .and_then(|v| v.as_str())\n            .unwrap_or(\"unknown\")\n            .to_string()\n    }\n\n    fn extract_video_url(detail: &serde_json::Value) -> Option<String> {\n        if let Some(play_addr) = detail.pointer(\"/video/playAddr\") {\n            if let Some(url) = play_addr.as_str() {\n                if Self::is_valid_play_addr(url) {","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/src/platforms/tiktok/mod.rs#L188-L224","documentation":"fetch_detail requires the itemStruct to contain an author object as a final sanity check. A missing author means TikTok returned a structurally-present but effectively empty itemStruct — the post is not actually retrievable (removed, blocked, or made private) even though status checks passed.","triggerScenarios":"get_media_info called on a post whose parsed itemStruct has no \"author\" key: recently deleted posts, private accounts, geo-blocked content, or a truncated/anti-bot payload from TikTok.","commonSituations":"Link to a deleted TikTok still circulating; account set to private after posting; TikTok serving an anonymized placeholder payload to suspicious clients.","solutions":["Confirm the post URL opens and shows the author in a logged-out browser.","Retry with captured cookies and a realistic User-Agent to get a full payload.","Fall back to get_media_info_via_ytdlp for a different extraction pipeline.","Treat as 'post unavailable' in the UI rather than retrying endlessly."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate the parsed struct before use\nif detail.get(\"author\").is_none() {\n    eprintln!(\"itemStruct has no author — post is unavailable\");\n}","typeGuard":"fn has_author(detail: &serde_json::Value) -> bool {\n    detail.get(\"author\").is_some()\n}","tryCatchPattern":"match get_media_info(url).await {\n    Err(e) if e.to_string() == \"Post not available\" => mark_post_unavailable(url),\n    other => other,\n}","preventionTips":["Check post availability in a browser before automating downloads.","Use valid cookies and realistic headers to avoid placeholder payloads.","Treat repeated occurrences for the same URL as a permanently dead post."],"tags":["tiktok","scraping","missing-field","post-unavailable"],"backgroundTag":"unexpected-response-shape","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"}