{"record":{"id":"ce2cae4ff11aaebd","repo":"DIYgod/RSSHub","slug":"invalid-type-type-valid-types-are-validtyp","errorCode":null,"errorMessage":"Invalid type: ${type}. Valid types are: ${validTypes}","messagePattern":"Invalid type: (.+?)\\. Valid types are: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/routes/zju/math/index.ts","lineNumber":128,"sourceCode":"        supportPodcast: false,\n        supportScihub: false,\n    },\n    name: '数学科学学院',\n    description: `| 重要通知 | 本科生 | 研究生 | 科研 | 教学 | 人事 | 公示 |\n| -------- | ------ | ------ | ---- | ---- | ---- | ---- |\n| 0        | 1      | 2      | 3    | 4    | 5    | 6    |`,\n    maintainers: ['Alex222222222222'],\n    handler,\n    url: 'www.math.zju.edu.cn',\n};\n\nasync function handler(ctx: Context) {\n    const type = Math.trunc(Number(ctx.req.param('type')));\n    const categoryInfo = categoryMap.get(type);\n\n    if (!categoryInfo) {\n        const validTypes = [...categoryMap.keys().toArray()].join(', ');\n        throw new Error(`Invalid type: ${type}. Valid types are: ${validTypes}`);\n    }\n\n    const categoryUrl = new URL(categoryInfo.id, base).href;\n    const newsItems = await fetchNewsItemsByCategory(categoryInfo.id);\n    const items = await Promise.all(newsItems.map((item) => enrichNewsItemWithDetails(item, categoryUrl)));\n\n    return {\n        title: categoryInfo.title,\n        link: categoryUrl,\n        item: items,\n    };\n}\n","sourceCodeStart":110,"sourceCodeEnd":141,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/zju/math/index.ts#L110-L141","documentation":"Thrown by the ZJU math route when the numeric `:type` path parameter does not correspond to any key in `categoryMap`. The handler truncates the param to an integer, looks it up in the map, and on a miss throws with the requested type and the full list of valid types for discoverability.","triggerScenarios":"The caller requests a `type` value not defined in the math route's `categoryMap` — an out-of-range integer, a non-numeric string that coerces to `NaN`/0, or a category that simply isn't modeled.","commonSituations":"User guesses a type number outside the documented 0–6 range; passes a category name instead of its numeric code; the URL was constructed with a stale/wrong index. `Math.trunc(Number('abc'))` yielding `NaN` is a common foot-gun.","solutions":["Read the valid types straight from the error message and use one of them (the route documents a 0–6 table).","If you derived the number from somewhere, verify it against the route's category table before requesting.","Guard non-numeric input upstream so it doesn't coerce to `NaN`/0 and silently pick the wrong category."],"exampleFix":"// before — out-of-range / non-numeric type\n// GET /zju/math/99   -> Invalid type: 99. Valid types are: 0, 1, 2, ...\n// GET /zju/math/news -> Invalid type: NaN ...\n// after — valid documented type\n// GET /zju/math/0","handlingStrategy":"validation","validationCode":"function validateMathType(raw, categoryMap) {\n    const type = Math.trunc(Number(raw));\n    if (!Number.isFinite(type) || !categoryMap.has(type)) {\n        throw new Error(`Invalid type: ${raw}. Valid: ${[...categoryMap.keys()].join(', ')}`);\n    }\n    return type;\n}","typeGuard":"function isValidMathType(raw: string, categoryMap: Map<number, unknown>): raw is `${number}` {\n    const n = Math.trunc(Number(raw));\n    return Number.isFinite(n) && categoryMap.has(n);\n}","tryCatchPattern":null,"preventionTips":["Validate and coerce the type to a finite integer in-range before the lookup.","Reject non-numeric input explicitly rather than letting it coerce to NaN/0.","Return the valid-types list in client-facing errors for quick self-service."],"tags":["zju","math","validation","route-parameter","allow-list"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}