tonhowtf/omniget · error

Pin not found

Error message

Pin not found

What it means

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.

Solutions

  1. Open the pin URL in a browser to confirm it still exists
  2. Handle this as a permanent error — do not retry the same pin ID
  3. Check the scraper isn't being served a soft-404 due to blocked/rate-limited access
  4. Ask the user for a corrected or alternative pin link

Example fix

// before
if Self::check_pin_not_found(&html) {
    return Err(anyhow!("Pin not found"));
}
// after
if Self::check_pin_not_found(&html) {
    return Err(PinterestError::PinNotFound(pin_id).into()); // non-retryable
}
Defensive patterns

Strategy: try-catch

Try / catch

match platform.get_media_info(url).await {
    Err(e) if e.to_string() == "Pin not found" => {
        eprintln!("This pin no longer exists or is private."); // permanent, no retry
    }
    other => other?,
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/72d30bbeccab846a. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/platforms/pinterest.rs:276

}

impl PinterestDownloader {
    async fn fallback_ytdlp(&self, url: &str) -> anyhow::Result<MediaInfo> {
        let ytdlp_path = crate::core::ytdlp::ensure_ytdlp().await?;
        let json = crate::core::ytdlp::get_video_info(&ytdlp_path, url, &[]).await?;
        crate::platforms::generic_ytdlp::GenericYtdlpDownloader::parse_video_info(&json)
    }

    async fn native_get_media_info(&self, url: &str) -> anyhow::Result<MediaInfo> {
        let canonical = self.resolve_pin_url(url).await?;

        let pin_id =
            Self::extract_pin_id(&canonical).ok_or_else(|| anyhow!("Could not extract pin ID"))?;

        let html = self.fetch_pin_html(&pin_id).await?;

        if Self::check_pin_not_found(&html) {
            return Err(anyhow!("Pin not found"));
        }

        if let Some(video_url) = Self::extract_video_url(&html) {
            return Ok(MediaInfo {
                title: format!("pinterest_{}", pin_id),
                author: String::new(),
                platform: "pinterest".to_string(),
                duration_seconds: None,
                thumbnail_url: None,
                available_qualities: vec![VideoQuality {
                    label: "original".to_string(),
                    width: 0,
                    height: 0,
                    url: video_url,
                    format: "mp4".to_string(),
                }],
                media_type: MediaType::Video,
                file_size_bytes: None,

View on GitHub (pinned to 8600b91f42)