tonhowtf/omniget · error

Could not extract data from embed

Error message

Could not extract data from embed

What it means

request_embed fetches the embed HTML page (https://www.instagram.com/p/{id}/embed/captioned/) and tries to scrape an embedded JSON payload via two regexes (the "init",[]... contextJSON blob or window.__additionalDataLoaded('extra', ...)). This error is thrown when neither regex matched the returned HTML, meaning Instagram served an embed page without extractable JSON data.

Solutions

  1. Inspect the raw embed HTML returned for the failing post_id and update the extraction regexes to the current markup.
  2. Check whether the request was redirected to a login or challenge page and handle that case explicitly.
  3. Confirm the post ID is valid by fetching /p/{id}/embed/ in a browser.
  4. Let the pipeline fall through to fallback_ytdlp, and keep yt-dlp updated as the last-resort extractor.
  5. Avoid calling request_embed for post types Instagram refuses to embed (e.g. private accounts).
Defensive patterns

Strategy: fallback

Validate before calling

// Confirm the post id is a plausible shortcode before hitting the embed page
fn plausible_shortcode(id: &str) -> bool {
    !id.is_empty() && id.len() <= 32 && id.chars().all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')
}

Try / catch

match request_embed(&post_id).await {
    Ok(data) => data,
    Err(e) if e.to_string().contains("Could not extract data from embed") => {
        // Instagram changed embed markup or served a challenge page; use yt-dlp fallback
        return fallback_ytdlp(url, &post_id).await;
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling get_media_info whose post_id leads to an embed page lacking both "init",[],[...] contextJSON and window.__additionalDataLoaded('extra', {...}) markers — typically when Instagram serves a login/consent wall, an error page, or changed its embed HTML template.

Common situations: Instagram A/B-tested or changed the embed page markup so the regexes no longer match; embeds disabled for the post; rate-limited request returned a challenge page; post ID invalid so embed returns an error page.

Related errors


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

Appendix: source

Thrown at src-tauri/omniget-core/src/platforms/instagram.rs:479

        if let Some(json_str) = Self::regex_extract(r#""init",\[\],\[(.*?)\]\],"#, &html) {
            if let Ok(embed_data) = serde_json::from_str::<serde_json::Value>(&json_str) {
                if let Some(context_json) = embed_data.get("contextJSON").and_then(|v| v.as_str()) {
                    let context: serde_json::Value = serde_json::from_str(context_json)?;
                    return Ok(context);
                }
            }
        }

        if let Some(json_str) = Self::regex_extract(
            r#"window\.__additionalDataLoaded\('extra',\s*(\{.*?\})\s*\)"#,
            &html,
        ) {
            let data: serde_json::Value = serde_json::from_str(&json_str)?;
            return Ok(data);
        }

        Err(anyhow!("Could not extract data from embed"))
    }

    async fn fallback_ytdlp(&self, url: &str, post_id: &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?;
        let mut info =
            crate::platforms::generic_ytdlp::GenericYtdlpDownloader::parse_video_info(&json)?;

        info.title = format!("instagram_{}", post_id);
        info.platform = "instagram".to_string();

        let post_url = format!("https://www.instagram.com/p/{}/", post_id);
        for q in &mut info.available_qualities {
            q.format = "ytdlp".to_string();
            q.url = post_url.clone();
        }

        Ok(info)

View on GitHub (pinned to 8600b91f42)