DIYgod/RSSHub · error · Error
Unhandled thirdparty on ${link}: ${elem.attr('alias')}
Error message
Unhandled thirdparty on ${link}: ${elem.attr('alias')} What it means
Thrown by the `card2Html` helper in the Yuque route while converting a Yuque `<card name="thirdparty">` (or `youku`) embed into HTML. The code only knows how to render the aliases `music163`, `bilibili`/`undefined`, and the `codepen` type; any other alias or type falls through to this throw. The message echoes the document `link` and the offending `alias` so a maintainer can identify which new third-party platform Yuque started supporting.
Source
Thrown at lib/routes/yuque/utils.ts:57
break;
case 'mention':
html = `<a href='https://www.yuque.com/${value.login}'>${value.name}</a>`;
break;
case 'table':
html = value.html;
break;
case 'thirdparty':
case 'youku':
// YES, youku name with bilibli iframe
// https://www.yuque.com/api/docs/nn5lyk?book_id=297292&include_contributors=true
if (elem.attr('alias') === 'music163') {
html = `<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" height=66 src="${value.src}"></iframe>`;
} else if (elem.attr('alias') === 'bilibili' || elem.attr('alias') === undefined) {
html = `<iframe src="${value.src}&high_quality=1&autoplay=0" width="650" height="477" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"></iframe>`;
} else if (value.type === 'codepen') {
html = `<iframe height="265" style="width: 100%;" scrolling="no" title="codepen" src="${value.url}" frameborder="no" allowtransparency="true" allowfullscreen="true"></iframe>`;
} else {
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}`);View on GitHub (pinned to bed535e087)
Solutions
- Read the `alias` value from the error message and add a new `else if` branch in the `thirdparty`/`youku` case that builds the correct iframe/HTML for that platform (typically using `value.src` or `value.url`).
- If the new embed is iframe-based, reuse the existing iframe template and swap in `value.src`/`value.url`.
- To stop one unknown embed from breaking the entire document feed, make the `else` branch skip the card (e.g. `html = ''` or leave `elem` in place) instead of throwing, and log the alias for follow-up.
Example fix
// before
} else {
throw new Error(`Unhandled thirdparty on ${link}: ${elem.attr('alias')}`);
}
// after (add a branch for the new alias)
} else if (elem.attr('alias') === 'codesandbox') {
html = `<iframe src="${value.src}" style="width:100%;height:500px;border:0;border-radius:4px;overflow:hidden;" allowfullscreen></iframe>`;
} else {
html = '';
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before calling card2Html, snapshot which card names/aliases appear
const knownThirdpartyAliases = new Set(['music163', 'bilibili', undefined]);
const knownThirdpartyTypes = new Set(['codepen']);
function isHandledThirdparty(elem, value) {
return knownThirdpartyAliases.has(elem.attr('alias')) || knownThirdpartyTypes.has(value.type);
} Type guard
function isHandledThirdparty(elem: cheerio.Cheerio<unknown>, value: { type?: string }): boolean {
const alias = elem.attr('alias');
return alias === 'music163' || alias === 'bilibili' || alias === undefined || value.type === 'codepen';
} Try / catch
// Wrap per-card conversion so one unhandled embed never kills the doc
try {
card2Html(elem, link);
} catch (e) {
logger.warn(`Skipping unhandled yuque thirdparty card on ${link}: ${(e as Error).message}`);
elem.remove();
} Prevention
- Wrap each card2Html call in try/catch so a single unknown embed degrades to a skipped card instead of failing the whole document.
- Maintain a known-types set and log the first occurrence of any new alias/type so you discover schema drift early.
- When adding a new third-party embed, add a regression document (a Yuque doc using it) to your test fixtures.
When it happens
Trigger: A Yuque document embeds a third-party widget whose `alias` attribute is something other than `music163` / `bilibili` / `undefined`, and whose parsed `value.type` is not `codepen` — e.g. a newly added platform like CodeSandbox, Figma, or a video host Yuque integrated after this branch was written.
Common situations: Yuque ships a new third-party embed integration; the alias naming for an existing platform changes; the `value.type === 'codepen'` check stops matching because Yuque restructured the card payload. Any single affected document breaks the whole feed because the throw is not caught.
Related errors
- Unhandled mode on ${link}: ${value.mode}
- Unhandled card on ${link}: ${name}
- Unknown type: ${contentItem.type}
- Unknown type: ${contentItem.type}
- Unknown type: ${item.type}
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/36e9ca14f48bff30.
Report an issue: GitHub.