microsoft/markitdown · error · ValueError

No channel found in RSS feed

Error message

No channel found in RSS feed

What it means

After _feed_type() classified the document as RSS (an <rss> element exists), _parse_rss_type() requires at least one <channel> child element. An <rss> root with no <channel> raises ValueError('No channel found in RSS feed'). Per the RSS 2.0 spec a channel is mandatory, so this fires on truncated or malformed feeds that still have the <rss> wrapper.

Source

Thrown at packages/markitdown/src/markitdown/converters/_rss_converter.py:141

            if entry_summary:
                md_text += self._parse_content(entry_summary)
            if entry_content:
                md_text += self._parse_content(entry_content)

        return DocumentConverterResult(
            markdown=md_text,
            title=title,
        )

    def _parse_rss_type(self, doc: Document) -> DocumentConverterResult:
        """Parse the type of an RSS feed.

        Returns None if the feed type is not recognized or something goes wrong.
        """
        root = doc.getElementsByTagName("rss")[0]
        channel_list = root.getElementsByTagName("channel")
        if not channel_list:
            raise ValueError("No channel found in RSS feed")
        channel = channel_list[0]
        channel_title = self._get_data_by_tag_name(channel, "title")
        channel_description = self._get_data_by_tag_name(channel, "description")
        items = channel.getElementsByTagName("item")
        if channel_title:
            md_text = f"# {channel_title}\n"
        if channel_description:
            md_text += f"{channel_description}\n"
        for item in items:
            title = self._get_data_by_tag_name(item, "title")
            description = self._get_data_by_tag_name(item, "description")
            pubDate = self._get_data_by_tag_name(item, "pubDate")
            content = self._get_data_by_tag_name(item, "content:encoded")

            if title:
                md_text += f"\n## {title}\n"
            if pubDate:
                md_text += f"Published on: {pubDate}\n"

View on GitHub (pinned to fd239d5d2b)

Solutions

  1. Check the feed with a validator (e.g. w3.org feed validator) and confirm the <channel> element exists inside <rss>
  2. Re-fetch the feed if it may have been truncated (verify Content-Length / try curl and inspect)
  3. If you control the producer, emit a valid RSS 2.0 document with a channel containing title/link/description
  4. Wrap conversion in a ValueError catch to skip malformed feeds in batch jobs

Example fix

# before
result = MarkItDown().convert('feed.rss')  # ValueError: No channel found in RSS feed

# after: pre-check structure
import defusedxml.minidom as minidom
doc = minidom.parse('feed.rss')
if not doc.getElementsByTagName('rss')[0].getElementsByTagName('channel'):
    raise SkipFile('malformed rss: no channel')
result = MarkItDown().convert('feed.rss')
Defensive patterns

Strategy: validation

Validate before calling

from defusedxml import minidom

def rss_has_channel(raw: bytes) -> bool:
    try:
        doc = minidom.parseString(raw)
        rss = doc.getElementsByTagName("rss")
        return bool(rss) and bool(rss[0].getElementsByTagName("channel"))
    except Exception:
        return False

Try / catch

try:
    result = MarkItDown().convert("feed.rss")
except ValueError as e:
    if "No channel found" in str(e):
        logger.warning("malformed/truncated RSS feed; skipping")  # skip in batch jobs

Prevention

When it happens

Trigger: Converting XML whose root is <rss> (e.g. <rss version='2.0'></rss> or <rss> containing only non-channel elements) with zero <channel> descendants; feeds truncated mid-transfer so the channel opening tag was lost; empty template files with just the rss skeleton.

Common situations: Scraping a partially downloaded feed over a flaky connection; feeds behind error pages that still emit an <rss> root; hand-built test fixtures missing the channel block.

Related errors


AI-assisted analysis of microsoft/markitdown@fd239d5d2b (2026-08-14). Data as JSON: /api/errors/aa907bc4c27eb168. Report an issue: GitHub.