ytdl-org/youtube-dl · error · ExtractorError

Unable to extract moment id

Error message

Unable to extract moment id

What it means

Raised inside _extract_moment (younow.py) when a moment item from the YouNow moments API has a falsy 'momentId' field and the fatal flag is True. Moments are short clips; without a momentId there is nothing to construct a URL from, so extraction cannot proceed. Callers that pass fatal=False get None back instead of the exception.

Source

Thrown at youtube_dl/extractor/younow.py:85

            'uploader_url': 'https://www.younow.com/%s' % username,
            'creator': uploader,
            'view_count': int_or_none(data.get('viewers')),
            'like_count': int_or_none(data.get('likes')),
            'formats': [{
                'url': '%s/broadcast/videoPath/hls=1/broadcastId=%s/channelId=%s'
                       % (CDN_API_BASE, data['broadcastId'], data['userId']),
                'ext': 'mp4',
                'protocol': 'm3u8',
            }],
        }


def _extract_moment(item, fatal=True):
    moment_id = item.get('momentId')
    if not moment_id:
        if not fatal:
            return
        raise ExtractorError('Unable to extract moment id')

    moment_id = compat_str(moment_id)

    title = item.get('text')
    if not title:
        title = 'YouNow %s' % (
            item.get('momentType') or item.get('titleType') or 'moment')

    uploader = try_get(item, lambda x: x['owner']['name'], compat_str)
    uploader_id = try_get(item, lambda x: x['owner']['userId'])
    uploader_url = 'https://www.younow.com/%s' % uploader if uploader else None

    entry = {
        'extractor_key': 'YouNowMoment',
        'id': moment_id,
        'title': title,
        'view_count': int_or_none(item.get('views')),
        'like_count': int_or_none(item.get('likes')),

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Inspect the failing item dict (log item.keys()) and confirm whether 'momentId' exists under a different key or nesting.
  2. If some items legitimately lack the id, call _extract_moment(item, fatal=False) so they are skipped instead of aborting the batch.
  3. Pre-filter the items list before extraction: keep only entries with a truthy 'momentId'.
  4. If the field was renamed by the API, update item.get('momentId') to the new key in younow.py.

Example fix

// before
entries = [_extract_moment(item) for item in items]

// after
entries = [_extract_moment(item, fatal=False) for item in items]
entries = [e for e in entries if e]
Defensive patterns

Strategy: validation

Validate before calling

def moment_items_valid(items) -> bool:
    return all(item.get('momentId') for item in items)

Type guard

def is_valid_moment(item: dict) -> bool:
    return isinstance(item, dict) and bool(item.get('momentId'))

Try / catch

try:
    entry = _extract_moment(item)
except ExtractorError as e:
    if 'Unable to extract moment id' in str(e):
        continue  # skip malformed/deleted moment in a batch
    raise

Prevention

When it happens

Trigger: Iterating channel moments where an entry in the API response lacks 'momentId' (deleted moments, placeholder entries, API schema drift) while calling _extract_moment with the default fatal=True.

Common situations: Channel scrape hit a moment deleted between listing and extraction; YouNow changed the field name (e.g. to 'momentId' vs an id nested object); processing raw API JSON that mixes non-moment entries into the items array.

Related errors


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