{"record":{"id":"72d30bbeccab846a","repo":"tonhowtf/omniget","slug":"pin-not-found","errorCode":null,"errorMessage":"Pin not found","messagePattern":"Pin not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/platforms/pinterest.rs","lineNumber":276,"sourceCode":"}\n\nimpl PinterestDownloader {\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 canonical = self.resolve_pin_url(url).await?;\n\n        let pin_id =\n            Self::extract_pin_id(&canonical).ok_or_else(|| anyhow!(\"Could not extract pin ID\"))?;\n\n        let html = self.fetch_pin_html(&pin_id).await?;\n\n        if Self::check_pin_not_found(&html) {\n            return Err(anyhow!(\"Pin not found\"));\n        }\n\n        if let Some(video_url) = Self::extract_video_url(&html) {\n            return Ok(MediaInfo {\n                title: format!(\"pinterest_{}\", pin_id),\n                author: String::new(),\n                platform: \"pinterest\".to_string(),\n                duration_seconds: None,\n                thumbnail_url: None,\n                available_qualities: vec![VideoQuality {\n                    label: \"original\".to_string(),\n                    width: 0,\n                    height: 0,\n                    url: video_url,\n                    format: \"mp4\".to_string(),\n                }],\n                media_type: MediaType::Video,\n                file_size_bytes: None,","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/platforms/pinterest.rs#L258-L294","documentation":"After fetching the pin's HTML, native_get_media_info() runs check_pin_not_found() on it; a positive match throws 'Pin not found'. Pinterest often returns HTTP 200 with a not-found/placeholder page, so this content-level check catches pins that the status code alone misses.","triggerScenarios":"The pin was deleted by its author, was removed for policy violations, is private/secret-board, or the pin ID is malformed-but-plausible so the server renders a 'not found' page.","commonSituations":"User copies a link to a pin deleted before the request; region-blocked pins render the not-found page; typos in manually typed pin URLs; bots receiving a soft-404 page due to blocked scraping.","solutions":["Open the pin URL in a browser to confirm it still exists","Handle this as a permanent error — do not retry the same pin ID","Check the scraper isn't being served a soft-404 due to blocked/rate-limited access","Ask the user for a corrected or alternative pin link"],"exampleFix":"// before\nif Self::check_pin_not_found(&html) {\n    return Err(anyhow!(\"Pin not found\"));\n}\n// after\nif Self::check_pin_not_found(&html) {\n    return Err(PinterestError::PinNotFound(pin_id).into()); // non-retryable\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match platform.get_media_info(url).await {\n    Err(e) if e.to_string() == \"Pin not found\" => {\n        eprintln!(\"This pin no longer exists or is private.\"); // permanent, no retry\n    }\n    other => other?,\n}","preventionTips":["Check the pin exists in a browser before automation","Never retry this error — it is a permanent condition for that pin ID","Validate pin IDs come from resolved, canonical URLs","Distinguish soft-404 pages from genuine scraper blocks (403/429 give different errors)"],"tags":["pinterest","scraping","not-found","http","soft-404"],"backgroundTag":"resource-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"}