{"record":{"id":"adc6482b1e5a0dba","repo":"tonhowtf/omniget","slug":"could-not-extract-user-and-post-id-from-url-mod","errorCode":null,"errorMessage":"Could not extract user and post_id from URL","messagePattern":"Could not extract user and post_id from URL","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/src/platforms/bluesky/mod.rs","lineNumber":33,"sourceCode":"    client: reqwest::Client,\n}\n\nimpl Default for BlueskyDownloader {\n    fn default() -> Self {\n        Self::new()\n    }\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,","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/src/platforms/bluesky/mod.rs#L15-L51","documentation":"In `native_get_media_info` (src-tauri/src/platforms/bluesky/mod.rs:33), `Self::extract_user_and_post(url)` failed to pull a valid username and post id (rkey) out of the given Bluesky URL, so the function aborts before calling the AppView API. The URL was not in a recognized bsky.app post format.","triggerScenarios":"Passing a URL that is not a bsky.app profile post link (e.g. a profile root, a search page, a shortened/rebranded host, or a malformed link) to get_media_info, so the regex/parser finds no user/post_id pair.","commonSituations":"Users paste their profile URL instead of a post URL; links copied from the Bluesky web app include extra query params or use alternate domains; URLs with escaped or truncated post ids.","solutions":["Verify the URL matches the expected post format: https://bsky.app/profile/<handle>/post/<rkey>.","Strip query strings and fragments before passing the URL.","Resolve alternate-domain links to the canonical bsky.app form first.","Improve `extract_user_and_post` to handle additional URL shapes (at:// URIs, staging domains)."],"exampleFix":"// before\nlet (user, post_id) = Self::extract_user_and_post(url)\n    .ok_or_else(|| anyhow!(\"Could not extract user and post_id from URL\"))?;\n// after\nlet url = url.split('?').next().unwrap_or(url);\nlet (user, post_id) = Self::extract_user_and_post(url)\n    .ok_or_else(|| anyhow!(\"Could not extract user and post_id from URL: {}\", url))?;","handlingStrategy":"validation","validationCode":"fn looks_like_bsky_post(url: &str) -> bool {\n    let u = url.split('?').next().unwrap_or(url);\n    u.starts_with(\"https://bsky.app/profile/\") && u.matches(\"/post/\").count() == 1\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate the URL shape before calling get_media_info.","Strip query strings and fragments from pasted links.","Normalize alternative Bluesky domains to bsky.app first."],"tags":["rust","bluesky","url-parsing","invalid-input"],"backgroundTag":"invalid-url-format","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"}