{"record":{"id":"bd9d6b00d5cd03a1","repo":"DIYgod/RSSHub","slug":"invalid-tab-tab","errorCode":null,"errorMessage":"Invalid tab: ${tab}","messagePattern":"Invalid tab: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/routes/voronoiapp/popular.ts","lineNumber":35,"sourceCode":"            source: ['www.voronoiapp.com/posts/most-discussed'],\n            target: '/popular/most-discussed',\n        },\n        {\n            title: 'Most Viewed Posts',\n            source: ['www.voronoiapp.com/posts/most-viewed'],\n            target: '/popular/most-viewed',\n        },\n    ],\n    parameters: {\n        tab: TabParam,\n        time_range: TimeRangeParam,\n        category: CategoryParam,\n    },\n    example: '/voronoiapp/popular/most-popular/MONTH',\n    handler: async (ctx) => {\n        const { tab = 'most-popular', time_range = 'MONTH', category = '' } = ctx.req.param();\n        if (!Object.hasOwn(TabMap, tab.toLowerCase())) {\n            throw new Error(`Invalid tab: ${tab}`);\n        }\n        const items = await getPostItems({\n            swimlane: 'POPULAR',\n            tab: TabMap[tab.toLowerCase()],\n            time_range: time_range === '' ? undefined : time_range.toUpperCase(),\n            category: category === '' ? undefined : category,\n        });\n        return {\n            ...CommonDataProperties,\n            title: `Voronoi ${TabParam.options.find((option) => option.value === tab.toLowerCase())?.label} Posts in ${TimeRangeParam.options.find((option) => option.value === time_range.toUpperCase())?.label}${category ? ` - ${category}` : ''}`,\n            link: `https://www.voronoiapp.com/posts/${tab}`,\n            item: items,\n        } as Data;\n    },\n};\n","sourceCodeStart":17,"sourceCodeEnd":51,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/voronoiapp/popular.ts#L17-L51","documentation":"Thrown by the Voronoi popular route handler when the `tab` path parameter, after lowercasing, is not a key in `TabMap` (`most-popular`, `most-discussed`, `most-viewed`). This is the route-level guard (line 34) that runs before calling `getPostItems`. It uses `Object.hasOwn(TabMap, tab.toLowerCase())`. This is a generic `Error`.","triggerScenarios":"A request to `/voronoiapp/popular/:tab` where `:tab` is not `most-popular`, `most-discussed`, or `most-viewed`. The parameter defaults to `most-popular`, so omitting it is safe. Only an explicit invalid value triggers the error.","commonSituations":"User guesses a tab name like `top` or `trending`, or uses the uppercase API value `POPULAR` instead of the lowercase path key `most-popular`.","solutions":["Use one of the lowercase tab keys: `most-popular`, `most-discussed`, or `most-viewed`.","Omit the tab parameter to default to `most-popular`.","Check the TabParam description table for valid values."],"exampleFix":"// before\nGET /voronoiapp/popular/trending\n// after\nGET /voronoiapp/popular/most-popular","handlingStrategy":"validation","validationCode":"if (!Object.hasOwn(TabMap, tab.toLowerCase())) {\n    throw new InvalidParameterError(\n        `Invalid tab: ${tab}. Valid: ${Object.keys(TabMap).join(', ')}`\n    );\n}","typeGuard":"function isValidPopularTab(tab: string): tab is 'most-popular' | 'most-discussed' | 'most-viewed' {\n    return Object.hasOwn(TabMap, tab.toLowerCase());\n}","tryCatchPattern":null,"preventionTips":["Use the lowercase kebab-case tab keys (most-popular, most-discussed, most-viewed), not the uppercase API values.","Include valid tab names in the error message.","Use InvalidParameterError instead of generic Error for consistency with RSSHub error semantics."],"tags":["parameter-validation","voronoiapp","rss-route","enum-validation"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}