{"record":{"id":"11e0f28cc5077edc","repo":"DIYgod/RSSHub","slug":"invalid-category-category","errorCode":null,"errorMessage":"Invalid category: ${category}","messagePattern":"Invalid category: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"lib/routes/cags/edu/index.ts","lineNumber":49,"sourceCode":"    name: '研究生院',\n    maintainers: ['Chikit-L'],\n    radar: [\n        {\n            source: ['edu.cags.ac.cn/'],\n        },\n    ],\n    handler,\n    description: `| 通知公告 | 要闻简讯 | 博士生招生 | 硕士生招生 | 大学生夏令营 |\n| -------- | -------- | ---------- | ---------- | ------------ |\n| tzgg     | ywjx     | zs\\\\_bss    | zs\\\\_sss    | zs\\\\_dxsxly   |`,\n};\n\nasync function handler(ctx) {\n    const category = ctx.req.param('category');\n    const title = titles[category];\n\n    if (!title) {\n        throw new Error(`Invalid category: ${category}`);\n    }\n\n    const API_URL = `${host}/api/cms/cmsNews/pageByCmsNavBarId/${category}/1/10/0`;\n    const response = await ofetch(API_URL);\n    const data = response.data;\n\n    const items = data.map((item) => {\n        const id = item.id;\n        const title = item.title;\n\n        let pubDate: Date | null = null;\n        if (item.publishDate) {\n            pubDate = parseDate(item.publishDate, 'YYYY-MM-DD');\n            pubDate = timezone(pubDate, 8);\n        }\n\n        const link = `${host}/#/dky/view/id=${id}/barId=${category}`;\n","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/cags/edu/index.ts#L31-L67","documentation":"Thrown by the CAGS (Chinese Academy of Governance Sciences) edu route when `category` is not a key in the `titles` map. Valid keys are tzgg, ywjx, zs_bss, zs_sss, zs_dxsxly (matching the description table). Uses a plain `Error`, not `InvalidParameterError`.","triggerScenarios":"Calling `/cags/edu/<category>` with a value outside {tzgg, ywjx, zs_bss, zs_sss, zs_dxsxly}. Note the description table escapes underscores as `zs\\_bss`; the real param uses a literal underscore.","commonSituations":"Copy-pasting the markdown-escaped value `zs\\_bss` verbatim (including the backslash), or dropping the underscore (`zsbss`).","solutions":["Use one of: tzgg, ywjx, zs_bss, zs_sss, zs_dxsxly (literal underscores, no backslash).","Maintainers: use `InvalidParameterError` and verify the description table does not mislead users with the markdown-escaped backslash-underscore."],"exampleFix":"// before\n/cags/edu/zs\\_bss\n// after\n/cags/edu/zs_bss","handlingStrategy":"validation","validationCode":"const CAGS_CATEGORIES = ['tzgg', 'ywjx', 'zs_bss', 'zs_sss', 'zs_dxsxly'] as const;\nfunction validateCagsCategory(c: string): void {\n    if (!(CAGS_CATEGORIES as readonly string[]).includes(c)) {\n        throw new Error(`Invalid category '${c}'. Use one of: ${CAGS_CATEGORIES.join(', ')}`);\n    }\n}","typeGuard":"const CAGS_CATEGORIES = ['tzgg', 'ywjx', 'zs_bss', 'zs_sss', 'zs_dxsxly'] as const;\ntype CagsCategory = typeof CAGS_CATEGORIES[number];\nfunction isCagsCategory(v: string): v is CagsCategory {\n    return (CAGS_CATEGORIES as readonly string[]).includes(v);\n}","tryCatchPattern":null,"preventionTips":["When reading category values from the docs table, strip the markdown-escape backslash: `zs\\_bss` → `zs_bss`.","Maintainers: fix the description table to avoid the escaped-underscore ambiguity."],"tags":["validation","user-input","route-parameter","markdown-escape"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}