DIYgod/RSSHub · warning · Error

Unsupported block type: ${b.__typename}

Error message

Unsupported block type: ${b.__typename}

What it means

The Verge article renderer maps each content block by its __typename to an HTML fragment. The switch handles a fixed set (images, slider, methodology accordion, product, table, etc.); the default branch throws for any block __typename the renderer has not implemented. This surfaces when The Verge's CMS ships a new block type that appears in an article body.

Source

Thrown at lib/routes/theverge/index.ts:93

            return `<blockquote>${b.children.map((child) => renderBlock(child)).join('')}</blockquote>`;
        case 'CoreSeparatorBlockType':
            return '<hr>';
        case 'HighlightBlockType':
            return b.children.map((c) => renderBlock(c)).join('');
        case 'ImageCompareBlockType':
            return `<figure><img src="${b.leftImage.thumbnails.horizontal.url.split('?', 1)[0]}" alt="${b.leftImage.alt}" /><img src="${b.rightImage.thumbnails.horizontal.url.split('?', 1)[0]}" alt="${b.rightImage.alt}" /><figcaption>${b.caption.html}</figcaption></figure>`;
        case 'ImageSliderBlockType':
            return b.images.map((i) => `<figure><img src="${i.image.originalUrl.split('?', 1)[0]}" alt="${i.alt}" /><figcaption>${i.caption.html}</figcaption></figure>`).join('');
        case 'MethodologyAccordionBlockType':
            return `<h2>${b.heading.html}</h2>${b.sections.map((s) => `<h3>${s.heading.html}</h3>${s.content.html}`).join('')}`;
        case 'ProductBlockType': {
            const product = b.product;
            return `<div><figure><img src="${product.image.thumbnails.horizontal.url.split('?', 1)[0]}" alt="${product.image.alt}" /><figcaption>${product.image.alt}</figcaption></figure><br><a href="${product.bestRetailLink.url}">${product.title} $${product.bestRetailLink.price}</a><br>${product.description.html}${product.pros.html ? `<br>The Good${product.pros.html}The Bad${product.cons.html}` : ''}</div>`;
        }
        case 'TableBlockType':
            return `<table><tr>${b.header.map((cell) => `<th>${cell}</th>`).join('')}</tr>${b.rows.map((row) => `<tr>${row.map((cell) => `<td>${cell}</td>`).join('')}</tr>`).join('')}</table>`;
        default:
            throw new Error(`Unsupported block type: ${b.__typename}`);
    }
};

async function handler(ctx) {
    const link = ctx.req.param('hub') ? `https://www.theverge.com/rss/${ctx.req.param('hub')}/index.xml` : 'https://www.theverge.com/rss/index.xml';

    const feed = await parser.parseURL(link);

    const items = await Promise.all(
        feed.items.map((item) =>
            cache.tryGet(item.link!, async () => {
                const response = await ofetch(item.link!);

                const $ = load(response);

                const nextData = JSON.parse($('script#__NEXT_DATA__').text());
                const node = nextData.props.pageProps.hydration.responses.find((x) => x.operationName === 'PostLayoutQuery' || x.operationName === 'StreamLayoutQuery').data.node;

View on GitHub (pinned to bed535e087)

Solutions

  1. Change the default branch to return a safe placeholder (e.g. b.caption?.html or '') instead of throwing, so one unknown block does not break the article.
  2. Identify the new __typename from the error, inspect its shape, and add a dedicated case.
  3. Log unknown block types so new types are noticed without breaking feeds.

Example fix

// before
default:
    throw new Error(`Unsupported block type: ${b.__typename}`);

// after: degrade gracefully and surface the unknown type in logs
default:
    console.warn(`Unknown Verge block type: ${b.__typename}`);
    return b.caption?.html ?? '';
Defensive patterns

Strategy: fallback

Validate before calling

const SUPPORTED_BLOCKS = new Set(['ImageBlockType', 'ImagePairBlockType', 'ImageSliderBlockType', 'MethodologyAccordionBlockType', 'ProductBlockType', 'TableBlockType']);
function isHandledBlock(typ: string): boolean {
    return SUPPORTED_BLOCKS.has(typ);
}
// before rendering, skip/placeholder unknown blocks rather than throwing

Type guard

function isHandledBlockType(typ: string): boolean {
    return ['ImageBlockType', 'ImagePairBlockType', 'ImageSliderBlockType', 'MethodologyAccordionBlockType', 'ProductBlockType', 'TableBlockType'].includes(typ);
}

Try / catch

try {
    return renderBlock(b);
} catch (e) {
    if (e instanceof Error && /Unsupported block type/.test(e.message)) {
        // degrade: render caption or empty string, log the new type
        console.warn(`Unknown Verge block: ${b.__typename}`);
        return (b as { caption?: { html?: string } }).caption?.html ?? '';
    }
    throw e;
}

Prevention

When it happens

Trigger: An article returned by the The Verge API contains a block whose __typename is not in the handled cases (e.g. a new 'NewsletterBlockType', 'VideoBlockType'). Rendering that article throws and the whole feed fetch can fail.

Common situations: The Verge adds a new CMS block; a one-off/embedded block type appears in a sponsored or feature article; the renderer was written against an older content schema.

Related errors


AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12). Data as JSON: /api/errors/1d5204c3f6130a22. Report an issue: GitHub.