{"record":{"id":"d6b6fe37f9feb162","repo":"DIYgod/RSSHub","slug":"unhandled-mode-on-link-value-mode","errorCode":null,"errorMessage":"Unhandled mode on ${link}: ${value.mode}","messagePattern":"Unhandled mode on (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/routes/yuque/utils.ts","lineNumber":66,"sourceCode":"            // YES, youku name with bilibli iframe\n            // https://www.yuque.com/api/docs/nn5lyk?book_id=297292&include_contributors=true\n            if (elem.attr('alias') === 'music163') {\n                html = `<iframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" height=66 src=\"${value.src}\"></iframe>`;\n            } else if (elem.attr('alias') === 'bilibili' || elem.attr('alias') === undefined) {\n                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>`;\n            } else if (value.type === 'codepen') {\n                html = `<iframe height=\"265\" style=\"width: 100%;\" scrolling=\"no\" title=\"codepen\" src=\"${value.url}\" frameborder=\"no\" allowtransparency=\"true\" allowfullscreen=\"true\"></iframe>`;\n            } else {\n                throw new Error(`Unhandled thirdparty on ${link}: ${elem.attr('alias')}`);\n            }\n            break;\n        case 'yuque':\n            if (value.mode === 'card') {\n                html = `<a href='${value.src}'>${value.detail.title}</a>`;\n            } else if (value.mode === 'embed') {\n                html = `<iframe src=\"${value.url}\" width=\"100%\" height=\"518\"></iframe>`;\n            } else {\n                throw new Error(`Unhandled mode on ${link}: ${value.mode}`);\n            }\n            break;\n        case 'video':\n            // fake video src\n            html = `<video src='${value.videoId}'></video>`;\n            break;\n\n        default:\n            throw new Error(`Unhandled card on ${link}: ${name}`);\n    }\n    elem.replaceWith(html);\n};\n\nexport { card2Html };\n","sourceCodeStart":48,"sourceCodeEnd":81,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/yuque/utils.ts#L48-L81","documentation":"Thrown by `card2Html` inside the `yuque` card case (a cross-document Yuque embed). It only handles `value.mode === 'card'` (renders a link) and `value.mode === 'embed'` (renders an iframe); any other mode value triggers this throw, reporting the document link and the unrecognized mode.","triggerScenarios":"A Yuque document uses a `<card name=\"yuque\">` embed whose `value.mode` is neither `'card'` nor `'embed'` — for instance Yuque adds a new preview/live-render mode, or the payload for an existing mode is restructured so the string no longer matches.","commonSituations":"Yuque introduces a new embed display mode; a mode string is renamed; the card payload's `mode` field is occasionally absent and coerced to a different value. The unhandled document then fails the entire feed.","solutions":["Inspect the `value.mode` reported in the error and add a matching `else if` branch that renders the embed appropriately.","If the new mode is link-like, reuse the `'card'` link template; if it is interactive, add an iframe template.","Make the final `else` degrade gracefully (render a fallback link to `value.src`) instead of throwing so one embed cannot kill the document."],"exampleFix":"// before\n} else if (value.mode === 'embed') {\n    html = `<iframe src=\"${value.url}\" width=\"100%\" height=\"518\"></iframe>`;\n} else {\n    throw new Error(`Unhandled mode on ${link}: ${value.mode}`);\n}\n// after\n} else if (value.mode === 'embed') {\n    html = `<iframe src=\"${value.url}\" width=\"100%\" height=\"518\"></iframe>`;\n} else {\n    html = `<a href='${value.src}'>${value.detail?.title ?? value.src}</a>`;\n}","handlingStrategy":"try-catch","validationCode":"const knownYuqueModes = new Set(['card', 'embed']);\nfunction isHandledYuqueMode(value) {\n    return knownYuqueModes.has(value.mode);\n}","typeGuard":"type YuqueCardValue = { mode?: string; src?: string; url?: string; detail?: { title?: string } };\nfunction isHandledYuqueMode(value: YuqueCardValue): boolean {\n    return value.mode === 'card' || value.mode === 'embed';\n}","tryCatchPattern":"try {\n    card2Html(elem, link);\n} catch (e) {\n    logger.warn(`Skipping unhandled yuque card mode on ${link}: ${(e as Error).message}`);\n    elem.replaceWith(`<a href='${link}'>[unsupported embed]</a>`);\n}","preventionTips":["Catch card2Html failures per element so unknown modes render a fallback link instead of aborting.","Track the set of modes you've seen in production logs to spot new ones Zhihu/Yuque ships.","Default unknown modes to a link to value.src when available rather than throwing."],"tags":["yuque","content-parsing","embed","switch-enum"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}