yt-dlp/yt-dlp · error · ExtractorError

Could not extract video id from recording

Error message

Could not extract video id from recording

What it means

Zattoo recordings are resolved to an internal program_id by scanning /zapi/v2/playlist for an entry whose id equals the recording id in the URL. This error means the playlist contained no such recording (StopIteration) or entries lacked usable program_id/recordings keys (KeyError). It is raised without expected=True, so unexpected playlist shapes surface as extraction failures.

Source

Thrown at yt_dlp/extractor/zattoo.py:70

        self._request_webpage(
            f'{self._host_url()}/zapi/v3/session/hello', None,
            'Opening session', data=urlencode_postdata({
                'uuid': str(uuid.uuid4()),
                'lang': 'en',
                'app_version': '1.8.2',
                'format': 'json',
                'client_app_token': session_token,
            }))

    def _extract_video_id_from_recording(self, recid):
        playlist = self._download_json(
            f'{self._host_url()}/zapi/v2/playlist', recid, 'Downloading playlist')
        try:
            return next(
                str(item['program_id']) for item in playlist['recordings']
                if item.get('program_id') and str(item.get('id')) == recid)
        except (StopIteration, KeyError):
            raise ExtractorError('Could not extract video id from recording')

    def _extract_cid(self, video_id, channel_name):
        channel_groups = self._download_json(
            f'{self._host_url()}/zapi/v2/cached/channels/{self._power_guide_hash}',
            video_id, 'Downloading channel list',
            query={'details': False})['channel_groups']
        channel_list = []
        for chgrp in channel_groups:
            channel_list.extend(chgrp['channels'])
        try:
            return next(
                chan['cid'] for chan in channel_list
                if chan.get('cid') and (
                    chan.get('display_alias') == channel_name
                    or chan.get('cid') == channel_name))
        except StopIteration:
            raise ExtractorError('Could not extract channel id')

View on GitHub (pinned to 81ecd58b13)

Solutions

  1. Log in with the owning account (--username/--password or --cookies-from-browser) so the playlist actually lists your recordings
  2. Verify the recording still exists by opening it in the Zattoo web app with the same account
  3. Copy the recording URL fresh from the web app to rule out truncated/mutated ids
  4. Update yt-dlp in case the playlist API shape changed and was patched

Example fix

# before (anonymous request -> empty personal playlist)
yt-dlp "https://zattoo.com/recording/123456"

# after (authenticated playlist lookup)
yt-dlp --cookies-from-browser chrome "https://zattoo.com/recording/123456"
Defensive patterns

Strategy: validation

Validate before calling

# Confirm the recording id looks like a Zattoo recording id before extracting
import re
m = re.search(r'/recording/(?P<id>\d+)', url)
assert m, 'URL does not contain a numeric recording id'
assert has_zattoo_session_cookies(), 'recording lookup needs an authenticated session'

Try / catch

from yt_dlp.utils import ExtractorError
try:
    ydl.download([url])
except ExtractorError as e:
    if 'Could not extract video id from recording' in str(e):
        # recording missing from the account playlist: verify in the web app, then drop
        mark_unavailable(url)
    else:
        raise

Prevention

When it happens

Trigger: A recording URL whose recid is not present in the account playlist (deleted recording, typo in id, or a playlist that requires authentication to include private recordings); upstream API change dropping/renaming the 'recordings' or 'program_id' fields.

Common situations: Recording was deleted on the account between listing and download attempt; extracting without being logged in so the personal playlist is empty; very old links with re-encoded ids; Zattoo API changes.

Related errors


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