DIYgod/RSSHub · error

Unhandled card on ${link}: ${name}

Error message

Unhandled card on ${link}: ${name}

What it means

The `default` arm of the `name` switch in `card2Html`. It fires when a Yuque `<card>` element has a `name` attribute not covered by any defined case (board, emoji, image, thirdparty, yuque, video, etc.). The message reports the document link and the unknown card name.

Source

Thrown at lib/routes/yuque/utils.ts:75

                throw new Error(`Unhandled thirdparty on ${link}: ${elem.attr('alias')}`);
            }
            break;
        case 'yuque':
            if (value.mode === 'card') {
                html = `<a href='${value.src}'>${value.detail.title}</a>`;
            } else if (value.mode === 'embed') {
                html = `<iframe src="${value.url}" width="100%" height="518"></iframe>`;
            } else {
                throw new Error(`Unhandled mode on ${link}: ${value.mode}`);
            }
            break;
        case 'video':
            // fake video src
            html = `<video src='${value.videoId}'></video>`;
            break;

        default:
            throw new Error(`Unhandled card on ${link}: ${name}`);
    }
    elem.replaceWith(html);
};

export { card2Html };

View on GitHub (pinned to bed535e087)

Solutions

  1. Take the `name` from the error message and add a `case` that maps it to the right HTML (often an `<img src='${value.src}'>` or `<a href='${value.src}'>` depending on the payload).
  2. If you cannot determine the right HTML yet, make the `default` arm non-fatal — replace the card with an empty string or a placeholder link so the rest of the document still renders.
  3. Add the new card name to the known list and open an upstream issue to track full support.

Example fix

// before
default:
    throw new Error(`Unhandled card on ${link}: ${name}`);
// after (graceful fallback + new case)
case 'callout':
    html = `<blockquote>${value.text ?? ''}</blockquote>`;
    break;
default:
    html = '';
    elem.remove();
    break;
Defensive patterns

Strategy: try-catch

Validate before calling

const knownCardNames = new Set([
    'board','emoji','flowchart2','image','math','mindmap','puml',
    'bookmarkInline','bookmarklink','yuqueinline','checkbox','codeblock',
    'diagram','file','localdoc','hr','label','mention','table',
    'thirdparty','youku','yuque','video',
]);
function isKnownCard(name) {
    return knownCardNames.has(name);
}

Type guard

function isKnownCardName(name: string | undefined): boolean {
    return typeof name === 'string' && KNOWN_CARD_NAMES.has(name);
}

Try / catch

try {
    card2Html(elem, link);
} catch (e) {
    logger.warn(`Skipping unhandled yuque card '${elem.attr('name')}' on ${link}`);
    elem.remove();
}

Prevention

When it happens

Trigger: Yuque introduces a brand-new block/card type (e.g. a callout, a new diagram kind, an attachment variant) so the serialized card carries a `name` value absent from the switch.

Common situations: Yuque releases a new editor feature; an existing card is renamed; the document was authored with a newer Yuque editor than the route supports. The throw aborts rendering of that document's whole body.

Related errors


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