{"record":{"id":"ba95056efe7c49db","repo":"DIYgod/RSSHub","slug":"invalid-isekai-ranking-type-type","errorCode":null,"errorMessage":"Invalid isekai ranking type: ${type}","messagePattern":"Invalid isekai ranking type: (.+?)","errorType":"validation","errorClass":"InvalidParameterError","httpStatus":503,"severity":"error","filePath":"lib/routes/syosetu/ranking-isekai.ts","lineNumber":22,"sourceCode":"import InvalidParameterError from '@/errors/types/invalid-parameter';\nimport type { Data, DataItem } from '@/types';\n\nimport { renderDescription } from './templates/description';\nimport { IsekaiCategory, isekaiCategoryToJapanese, NovelType, novelTypeToJapanese, periodToJapanese, periodToOrder, periodToPointField, RankingPeriod } from './types/ranking';\n\ntype Join<T extends string | number> = `${T}-${T}` | `${T}`;\n\nexport function parseIsekaiRankingType(type: string): { period: RankingPeriod; category: IsekaiCategory; novelType: NovelType } {\n    const [periodStr, categoryStr, novelTypeStr = NovelType.TOTAL] = type.split('_', 3);\n\n    const period = periodStr as RankingPeriod;\n    const category = categoryStr as IsekaiCategory;\n    const novelType = novelTypeStr as NovelType;\n\n    const isValid = [Object.values(RankingPeriod).includes(period), Object.values(IsekaiCategory).includes(category), Object.values(NovelType).includes(novelType)].every(Boolean);\n\n    if (!isValid) {\n        throw new InvalidParameterError(`Invalid isekai ranking type: ${type}`);\n    }\n\n    return { period, category, novelType };\n}\n\nfunction getIsekaiSearchParams(period, category, novelType, limit): SearchParams {\n    const searchParams: SearchParams = {\n        order: periodToOrder[period],\n        gzip: 5,\n        // Request 20% more items to compensate for potential duplicates between tensei/tenni\n        lim: Math.ceil((limit / 2) * 1.2),\n    };\n\n    if (novelType !== NovelType.TOTAL) {\n        searchParams.type = novelType;\n    }\n\n    switch (category) {","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/syosetu/ranking-isekai.ts#L4-L40","documentation":"Thrown by parseIsekaiRankingType (syosetu/ranking-isekai.ts:22) as an InvalidParameterError when the isekai ranking `type` string (format period_category_novelType) has ANY component that is not a valid enum value. Valid periods (RankingPeriod): daily, weekly, monthly, quarter, yearly, total. Valid categories (IsekaiCategory): '1' (Renai), '2' (Fantasy), 'o' (Other). Valid novelTypes (NovelType): total, t, r, er. novelType defaults to 'total' if omitted. Reached via /syosetu/ranking/isekai/<type>.","triggerScenarios":"Malformed type: wrong segment order, missing category, unknown period (e.g. 'annual'), unknown category (e.g. '3'), unknown novelType (e.g. 're' — note 're' is a valid NarouSearchParams type but NOT a NovelType ranking value), or extra underscore segments.","commonSituations":"Hand-building the URL without consulting the route's parameters.type.options table; confusing the isekai format (period_category_novelType) with the genre format (period_genre_novelType); copy-pasting a genre-ranking URL into the isekai route.","solutions":["Use the exact format <period>_<category>_<novelType> with only valid values, e.g. daily_2_total or weekly_1_r.","Remember novelType is optional and defaults to total, so daily_2 is also valid.","Pick a known-good value from the route's parameters.type.options (auto-generated from the enums)."],"exampleFix":"// before\nGET /syosetu/ranking/isekai/daily_3_total\n// after (category must be 1, 2, or o)\nGET /syosetu/ranking/isekai/daily_2_total","handlingStrategy":"validation","validationCode":"import { RankingPeriod, NovelType, IsekaiCategory } from './types/ranking';\n\nconst PERIODS = Object.values(RankingPeriod);\nconst CATEGORIES = Object.values(IsekaiCategory);\nconst NOVEL_TYPES = Object.values(NovelType);\n\nfunction isValidIsekaiType(type: string): boolean {\n  const [p, c, n = NovelType.TOTAL] = type.split('_', 3);\n  return PERIODS.includes(p as RankingPeriod)\n    && CATEGORIES.includes(c as IsekaiCategory)\n    && NOVEL_TYPES.includes(n as NovelType);\n}","typeGuard":"function isIsekaiRankingType(type: string): boolean {\n  const [p, c, n = 'total'] = type.split('_', 3);\n  return ['daily','weekly','monthly','quarter','yearly','total'].includes(p)\n    && ['1','2','o'].includes(c)\n    && ['total','t','r','er'].includes(n);\n}","tryCatchPattern":null,"preventionTips":["Use the format <period>_<category>_<novelType> with category in {1, 2, o}.","Pick values from the route's parameters.type.options table rather than hand-typing.","Remember novelType is optional and defaults to total."],"tags":["invalid-parameter","enum","syosetu","ranking","isekai"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}