{"record":{"id":"39984c9110680792","repo":"tonhowtf/omniget","slug":"post-does-not-contain-media-mod","errorCode":null,"errorMessage":"Post does not contain media","messagePattern":"Post does not contain media","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/src/platforms/bluesky/mod.rs","lineNumber":39,"sourceCode":"    }\n}\n\nimpl BlueskyDownloader {\n    async fn fallback_ytdlp(&self, url: &str) -> anyhow::Result<MediaInfo> {\n        let ytdlp_path = crate::core::ytdlp::ensure_ytdlp().await?;\n        let json = crate::core::ytdlp::get_video_info(&ytdlp_path, url, &[]).await?;\n        crate::platforms::generic_ytdlp::GenericYtdlpDownloader::parse_video_info(&json)\n    }\n\n    async fn native_get_media_info(&self, url: &str) -> anyhow::Result<MediaInfo> {\n        let (user, post_id) = Self::extract_user_and_post(url)\n            .ok_or_else(|| anyhow!(\"Could not extract user and post_id from URL\"))?;\n\n        let json = self.fetch_post(&user, &post_id).await?;\n\n        let embed = json\n            .pointer(\"/thread/post/embed\")\n            .ok_or_else(|| anyhow!(\"Post does not contain media\"))?;\n\n        let media = extract_media(embed).ok_or_else(|| anyhow!(\"Unsupported media type\"))?;\n\n        let filename_base = format!(\"bluesky_{}_{}\", sanitize_filename::sanitize(&user), post_id);\n\n        match media {\n            BlueskyMedia::Video { hls_url } => Ok(MediaInfo {\n                title: filename_base,\n                author: user,\n                platform: \"bluesky\".to_string(),\n                duration_seconds: None,\n                thumbnail_url: None,\n                available_qualities: vec![VideoQuality {\n                    label: \"best\".to_string(),\n                    width: 0,\n                    height: 0,\n                    url: hls_url,\n                    format: \"hls\".to_string(),","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/src/platforms/bluesky/mod.rs#L21-L57","documentation":"In `native_get_media_info` (src-tauri/src/platforms/bluesky/mod.rs:39), the JSON pointer `/thread/post/embed` was absent from the fetched post record, meaning the Bluesky AppView returned a post with no embed at all. Only posts with attached media (or external embeds) carry this field.","triggerScenarios":"Fetching a text-only post, a deleted or gated post that returns a skeleton without embed, or a reply/repost whose thread shape differs, then calling `.pointer(\"/thread/post/embed\")` which yields None.","commonSituations":"User shares a Bluesky post that has no images or video; post was deleted between copying the link and downloading; post from a blocked/moderated account returns a truncated thread object.","solutions":["Confirm the post actually contains images or video before attempting download.","Check the full API response for `thread.$type === 'app.bsky.feed.defs#notFoundPost'` and surface a clearer message.","Use a null-tolerant path like `pointer(\"/thread/post/embed\")` combined with an explicit not-found check on `thread` to distinguish 'no media' from 'post missing'.","Fall back to the generic ytdlp path for posts without native embeds."],"exampleFix":"// before\nlet embed = json.pointer(\"/thread/post/embed\")\n    .ok_or_else(|| anyhow!(\"Post does not contain media\"))?;\n// after\nif json.pointer(\"/thread/$type\").is_some_and(|t| t.as_str().unwrap_or_default().contains(\"notFoundPost\")) {\n    anyhow::bail!(\"Post not found or deleted\");\n}\nlet embed = json.pointer(\"/thread/post/embed\")\n    .ok_or_else(|| anyhow!(\"Post does not contain media\"))?;","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"fn has_embed(thread: &serde_json::Value) -> bool {\n    thread.pointer(\"/post/embed\").is_some()\n}","tryCatchPattern":"let Some(embed) = json.pointer(\"/thread/post/embed\") else {\n    anyhow::bail!(\"Post has no media embed (is it a text-only post?)\");\n};","preventionTips":["Check for the notFoundPost thread type before assuming a live post.","Inform users that only posts with attached images or video are supported.","Validate the embed path exists before pointer navigation."],"tags":["rust","bluesky","missing-field","no-media"],"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"}