ytdl-org/youtube-dl · warning · ExtractorError

No media links available for %s

Error message

No media links available for %s

What it means

Raised by the Lifenews extractor when the article page contains neither <video><source src=...> elements nor iframes pointing at embed.life.ru. It is not expected=True, so it can bubble up as an extractor error even for articles that legitimately have no media (text/photo-only posts).

Source

Thrown at youtube_dl/extractor/lifenews.py:106

    }, {
        'url': 'https://life.ru/t/новости/411489/manuel_vals_nazval_frantsiiu_tsieliu_nomier_odin_dlia_ighil',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url)

        webpage = self._download_webpage(url, video_id)

        video_urls = re.findall(
            r'<video[^>]+><source[^>]+src=["\'](.+?)["\']', webpage)

        iframe_links = re.findall(
            r'<iframe[^>]+src=["\']((?:https?:)?//embed\.life\.ru/(?:embed|video)/.+?)["\']',
            webpage)

        if not video_urls and not iframe_links:
            raise ExtractorError('No media links available for %s' % video_id)

        title = remove_end(
            self._og_search_title(webpage),
            ' - Life.ru')

        description = self._og_search_description(webpage)

        view_count = self._html_search_regex(
            r'<div[^>]+class=(["\']).*?\bhits-count\b.*?\1[^>]*>\s*(?P<value>\d+)\s*</div>',
            webpage, 'view count', fatal=False, group='value')

        timestamp = parse_iso8601(self._search_regex(
            r'<time[^>]+datetime=(["\'])(?P<value>.+?)\1',
            webpage, 'upload date', fatal=False, group='value'))

        common_info = {
            'description': description,
            'view_count': int_or_none(view_count),

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Check the article in a browser — if it truly has no video, skip such URLs during bulk runs
  2. Update youtube-dl/yt-dlp in case the embed markup/regex changed
  3. If the video is JS-injected, find the underlying embed URL in the page's scripts and pass it directly
  4. For bulk jobs, pre-filter article URLs by a quick content check or tolerate this error per-URL

Example fix

# before: whole-channel bulk run stops on text-only posts
# youtube-dl 'http://lifenews.ru/news/123456'

# after: continue past media-less articles
# youtube-dl --ignore-errors 'http://lifenews.ru/news/123456'
Defensive patterns

Strategy: try-catch

Validate before calling

import re

def lifenews_page_has_media(page_html):
    return bool(
        re.search(r'<video[^>]+><source[^>]+src=["\']', page_html)
        or re.search(r'<iframe[^>]+src=["\'](?:https?:)?//embed\.life\.ru/(?:embed|video)/', page_html)
    )

Try / catch

try:
    ydl.extract_info(url)
except ExtractorError as e:
    if 'No media links available' in str(e):
        continue  # text-only article; expected during feed archiving
    raise

Prevention

When it happens

Trigger: Downloading a lifenews.ru article URL that is a plain text/photo news post with no video markup, or one whose video embed markup changed so both regexes (native <source> and embed.life.ru iframes) fail to match.

Common situations: Bulk-archiving news feeds where many articles have no video; Life.ru changing their embed domain or markup; videos injected only via JS after load; old youtube-dl versions with stale iframe regexes.

Related errors


AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14). Data as JSON: /api/errors/371adb31d6d9b351. Report an issue: GitHub.