yt-dlp/yt-dlp · error · ExtractorError

Unable to find provider video id

Error message

Unable to find provider video id

What it means

VoxMediaIE's _VALID_URL is very broad and matches nearly any page on the Vox Media domains. When the page's video_data JSON has neither a youtube_id nor a brightcove_id and no direct formats were extracted, there is no provider to hand off to, so the extractor gives up with this generic message.

Source

Thrown at yt_dlp/extractor/voxmedia.py:68

            info['formats'] = formats
            info['duration'] = int_or_none(asset.get('duration'))
            return info

        for provider_video_type in ('youtube', 'brightcove'):
            provider_video_id = video_data.get(f'{provider_video_type}_id')
            if not provider_video_id:
                continue
            if provider_video_type == 'brightcove':
                # TODO: Find embed example or confirm that Vox has stopped using Brightcove
                raise ExtractorError('Vox Brightcove embeds are currently unsupported')
            else:
                info.update({
                    '_type': 'url_transparent',
                    'url': provider_video_id if provider_video_type == 'youtube' else f'{provider_video_type}:{provider_video_id}',
                    'ie_key': provider_video_type.capitalize(),
                })
            return info
        raise ExtractorError('Unable to find provider video id')


class VoxMediaIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?(?:(?:theverge|vox|sbnation|eater|polygon|curbed|racked|funnyordie)\.com|recode\.net)/(?:[^/]+/)*(?P<id>[^/?]+)'
    _EMBED_REGEX = [r'<iframe[^>]+?src="(?P<url>https?://(?:www\.)?funnyordie\.com/embed/[^"]+)"']
    _TESTS = [{
        # FIXME: Unsupported iframe embed
        # Volume embed, Youtube
        'url': 'http://www.theverge.com/2014/6/27/5849272/material-world-how-google-discovered-what-software-is-made-of',
        'info_dict': {
            'id': 'j4mLW6x17VM',
            'ext': 'mp4',
            'title': 'Material world: how Google discovered what software is made of',
            'description': 'md5:dfc17e7715e3b542d66e33a109861382',
            'upload_date': '20190710',
            'uploader_id': 'TheVerge',
            'uploader': 'The Verge',
        },

View on GitHub (pinned to 81ecd58b13)

Solutions

  1. Confirm the URL actually contains a video by opening it in a browser
  2. Find the real embed (iframe src or YouTube link) in the page HTML and pass that URL to yt-dlp directly
  3. If the video plays in a browser but yt-dlp fails, run with --verbose to see which JSON was parsed and report the missed embed pattern upstream
Defensive patterns

Strategy: validation

Validate before calling

import json, re, urllib.request

page = urllib.request.urlopen(article_url).read().decode()
m = re.search(r'Chorus\.VideoContext\.prepare\((\{.*?\})\);?\s*$', page, re.M)
video_data = json.loads(m.group(1))['video'] if m else {}
if not any(video_data.get(k) for k in ('youtube_id', 'brightcove_id')) and not video_data.get('video_files'):
    print('no provider video on this page, skip yt-dlp call')

Type guard

def is_no_provider_video(exc: Exception) -> bool:
    return isinstance(exc, ExtractorError) and 'Unable to find provider video id' in str(exc)

Try / catch

try:
    info = ydl.extract_info(url, download=False)
except DownloadError as e:
    if 'Unable to find provider video id' in str(e):
        continue  # non-video article, skip in batch runs
    raise

Prevention

When it happens

Trigger: Passing a Vox Media URL that matches the regex but whose init JSON contains no youtube_id/brightcove_id and no formats: photo galleries, text-only articles, hub/index pages, or pages whose video is embedded via an iframe type the extractor does not parse.

Common situations: Non-video articles (the URL regex matches any slug ending a path); embeds via unsupported iframe providers; renamed or redirected URLs that still match the pattern.

Related errors


AI-assisted analysis of yt-dlp/yt-dlp@81ecd58b13 (2026-08-22). Data as JSON: /api/errors/67b3111651613903. Report an issue: GitHub.