{"record":{"id":"a55206c9d685f69e","repo":"DIYgod/RSSHub","slug":"invalid-room-id-room-id-should-be-a-number","errorCode":null,"errorMessage":"Invalid room ID. Room ID should be a number.","messagePattern":"Invalid room ID\\. Room ID should be a number\\.","errorType":"validation","errorClass":"InvalidParameterError","httpStatus":503,"severity":"error","filePath":"lib/routes/douyin/live.ts","lineNumber":36,"sourceCode":"        antiCrawler: true,\n        supportBT: false,\n        supportPodcast: false,\n        supportScihub: false,\n    },\n    radar: [\n        {\n            source: ['live.douyin.com/:rid'],\n        },\n    ],\n    name: '直播间开播',\n    maintainers: ['TonyRL'],\n    handler,\n};\n\nasync function handler(ctx) {\n    const rid = ctx.req.param('rid');\n    if (Number.isNaN(rid)) {\n        throw new InvalidParameterError('Invalid room ID. Room ID should be a number.');\n    }\n\n    const pageUrl = `https://live.douyin.com/${rid}`;\n\n    const renderData = await cache.tryGet(\n        `douyin:live:${rid}`,\n        async () => {\n            let roomInfo;\n            const context = await playwright();\n            const page = await context.newPage();\n            await page.route('**/*', (route) => {\n                const request = route.request();\n                request.resourceType() === 'document' || request.resourceType() === 'stylesheet' || request.resourceType() === 'script' || request.resourceType() === 'xhr' ? route.continue() : route.abort();\n            });\n            page.on('response', async (response) => {\n                const request = response.request();\n                if (request.url().includes('/webcast/room/web/enter')) {\n                    roomInfo = await response.json();","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/douyin/live.ts#L18-L54","documentation":"Thrown by the Douyin live room route when the `rid` path parameter fails the numeric validation. This has the same BUG as the hashtag route: `Number.isNaN(rid)` where `rid` is a string from `ctx.req.param()` — `Number.isNaN()` only returns true for the value `NaN`, never for strings, so the check is always `false` and the error is never thrown. Non-numeric room IDs silently pass through and cause failures downstream.","triggerScenarios":"Supplying a non-numeric rid (e.g. /douyin/live/abc) — due to the bug, the validation does NOT fire; the Playwright navigation to live.douyin.com/abc proceeds and either redirects or returns unexpected data, causing a different error downstream (e.g. undefined property access on renderData).","commonSituations":"Developer expects validation to catch bad input but it doesn't; the error message exists as dead code; fixing the guard to actually reject non-numeric IDs.","solutions":["Fix the validation: change `Number.isNaN(rid)` to `Number.isNaN(Number(rid))`.","If you are a user (post-fix), ensure rid is the numeric room ID from the Douyin live URL (e.g. https://live.douyin.com/685317364746 → rid=685317364746).","Find the correct rid from the live.douyin.com URL."],"exampleFix":"// before (BUG: never fires for string input)\nconst rid = ctx.req.param('rid');\nif (Number.isNaN(rid)) {\n    throw new InvalidParameterError('Invalid room ID. Room ID should be a number.');\n}\n\n// after\nconst rid = ctx.req.param('rid');\nif (Number.isNaN(Number(rid))) {\n    throw new InvalidParameterError('Invalid room ID. Room ID should be a number.');\n}","handlingStrategy":"validation","validationCode":"// Correctly validate that rid is a numeric string\nfunction isValidDouyinRid(rid: string): boolean {\n    return /^\\d+$/.test(rid);\n}\n\nconst rid = userInput;\nif (!isValidDouyinRid(rid)) {\n    throw new Error(`Invalid room ID '${rid}'. Must be a numeric string.`);\n}","typeGuard":"function isNumericRid(value: string): boolean {\n    return /^\\d+$/.test(value);\n}","tryCatchPattern":"try {\n    const feed = await fetch(`${rsshubUrl}/douyin/live/${rid}`);\n} catch (e) {\n    if (e.message.includes('Invalid room ID')) {\n        console.error(`rid must be numeric, got: ${rid}`);\n    }\n    throw e;\n}","preventionTips":["NOTE: The current validation has the same Number.isNaN() bug as the hashtag route. Validate client-side with /^\\d+$/.test(rid).","Extract the rid from the Douyin live URL: https://live.douyin.com/<rid>.","If maintaining this route, fix the guard to Number.isNaN(Number(rid))."],"tags":["douyin","invalid-parameter","validation-bug","number-isnan","javascript"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}