ytdl-org/youtube-dl · error · ExtractorError

Missing "title" field in extractor result

Error message

Missing "title" field in extractor result

What it means

Raised by xpath_text when the matched element exists but has no text content (node.text is None), no default was given, and fatal=True. Distinct from 'Could not find XML element': here the XPath matched an empty element (<Title/> or <Title></Title>), so the node exists but its text is absent.

Source

Thrown at youtube_dl/YoutubeDL.py:1651

                    upload_date = datetime.datetime.utcfromtimestamp(info_dict[ts_key])
                    info_dict[date_key] = compat_str(upload_date.strftime('%Y%m%d'))
                except (ValueError, OverflowError, OSError):
                    pass

        # Auto generate title fields corresponding to the *_number fields when missing
        # in order to always have clean titles. This is very common for TV series.
        if final:
            for field in ('chapter', 'season', 'episode'):
                if info_dict.get('%s_number' % field) is not None and not info_dict.get(field):
                    info_dict[field] = '%s %d' % (field.capitalize(), info_dict['%s_number' % field])

    def process_video_result(self, info_dict, download=True):
        assert info_dict.get('_type', 'video') == 'video'

        if 'id' not in info_dict:
            raise ExtractorError('Missing "id" field in extractor result')
        if 'title' not in info_dict:
            raise ExtractorError('Missing "title" field in extractor result')

        def report_force_conversion(field, field_not, conversion):
            self.report_warning(
                '"%s" field is not %s - forcing %s conversion, there is an error in extractor'
                % (field, field_not, conversion))

        def sanitize_string_field(info, string_field):
            field = info.get(string_field)
            if field is None or isinstance(field, compat_str):
                return
            report_force_conversion(string_field, 'a string', 'string')
            info[string_field] = compat_str(field)

        def sanitize_numeric_fields(info):
            for numeric_field in self._NUMERIC_FIELDS:
                field = info.get(numeric_field)
                if field is None or isinstance(field, compat_numeric_types):
                    continue

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Pass default='' (or another sentinel) or fatal=False so empty text returns the default/None instead of raising.
  2. Verify the XPath points at the leaf element that actually carries text, not a container.
  3. Update youtube-dl / yt-dlp if this comes from a built-in extractor reacting to a schema change.
  4. When iterating many items, catch ExtractorError per item and skip only the affected entry.

Example fix

# before
duration = xpath_text(item, 'duration', fatal=True)

# after
duration = xpath_text(item, 'duration', default=None)
if duration is not None:
    duration = parse_duration(duration)
Defensive patterns

Strategy: validation

Validate before calling

from youtube_dl.utils import xpath_element

# pre-check text instead of letting xpath_text raise
node = xpath_element(doc, xpath, fatal=False, default=None)
text = node.text if (node is not None and node.text is not None) else None
if text is None:
    text = fallback

Try / catch

from youtube_dl.utils import ExtractorError, xpath_text
try:
    val = xpath_text(doc, '//Title', name='title', fatal=True)
except ExtractorError as e:
    if "element's text" in str(e):
        val = ''  # element exists but is empty — treat as empty string
    else:
        raise

Prevention

When it happens

Trigger: xpath_text(node, xpath, fatal=True) where the document contains the element empty. Common with optional API fields serialized as empty tags, or elements that carry only attributes/children and no text.

Common situations: Site API starts returning empty tags for missing values instead of omitting them; extractors that treat such fields as mandatory; namespace/structure changes where the XPath matches a wrapper element whose text moved to a child.

Related errors


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