DIYgod/RSSHub · warning · InvalidParameterError

Invalid Isekai category: ${category}

Error message

Invalid Isekai category: ${category}

What it means

Defensive default arm in getIsekaiSearchParams (syosetu/ranking-isekai.ts:51) thrown as an InvalidParameterError when the category switch falls through. In the NORMAL call path this is UNREACHABLE: the sole caller handleIsekaiRanking always invokes parseIsekaiRankingType first, which already validates category against IsekaiCategory and throws [525] on failure. This guard only fires if getIsekaiSearchParams is called directly with an unvalidated category, or if a new IsekaiCategory member is added to the enum without a matching case here (TypeScript exhaustiveness is not enforced because the switch is on a loosely-typed value).

Source

Thrown at lib/routes/syosetu/ranking-isekai.ts:51

        lim: Math.ceil((limit / 2) * 1.2),
    };

    if (novelType !== NovelType.TOTAL) {
        searchParams.type = novelType;
    }

    switch (category) {
        case IsekaiCategory.RENAI:
            searchParams.biggenre = BigGenre.Renai;
            break;
        case IsekaiCategory.FANTASY:
            searchParams.biggenre = BigGenre.Fantasy;
            break;
        case IsekaiCategory.OTHER:
            searchParams.biggenre = `${BigGenre.Bungei}-${BigGenre.Sf}-${BigGenre.Sonota}` as unknown as Join<BigGenre>;
            break;
        default:
            throw new InvalidParameterError(`Invalid Isekai category: ${category}`);
    }

    return searchParams;
}

export async function handleIsekaiRanking(type: string, limit: number): Promise<Data> {
    const { period, category, novelType } = parseIsekaiRankingType(type);
    const rankingUrl = `https://yomou.syosetu.com/rank/isekailist/type/${type}`;
    const rankingTitle = `[${periodToJapanese[period]}] 異世界転生/転移${isekaiCategoryToJapanese[category]}ランキング - ${novelTypeToJapanese[novelType]} BEST${limit}`;

    const searchParams = getIsekaiSearchParams(period, category, novelType, limit);
    const api = new NarouNovelFetch();

    const [tenseiResult, tenniResult] = await Promise.all([new SearchBuilder({ ...searchParams, istensei: 1 }, api).execute(), new SearchBuilder({ ...searchParams, istenni: 1 }, api).execute()]);

    const combinedNovels = [...tenseiResult.values, ...tenniResult.values];
    const uniqueNovels = new Map(combinedNovels.map((novel) => [novel.ncode, novel])).values().toArray();

View on GitHub (pinned to bed535e087)

Solutions

  1. If you added an IsekaiCategory member, add the matching case in getIsekaiSearchParams (mapping to the correct BigGenre).
  2. Never call getIsekaiSearchParams without first running the type through parseIsekaiRankingType.

Example fix

// before (new enum member added, switch falls through)
case IsekaiCategory.NEW_VALUE:
    // missing -> hits default throw
// after
case IsekaiCategory.NEW_VALUE:
    searchParams.biggenre = BigGenre.SomeGenre;
    break;
Defensive patterns

Strategy: validation

Validate before calling

// Unreachable in normal flow; only relevant when extending the enum.
// Ensure every enum member has a switch case at compile time.
function assertExhaustive(category: IsekaiCategory): never {
  throw new Error(`Unhandled IsekaiCategory: ${category as string}`);
}

Type guard

import { IsekaiCategory } from './types/ranking';

const CATEGORY_TO_BIGGENRE: Record<IsekaiCategory, unknown> = {
  [IsekaiCategory.RENAI]: 'renai',
  [IsekaiCategory.FANTASY]: 'fantasy',
  [IsekaiCategory.OTHER]: 'bungei-sf-sonota',
};

function hasBigGenreMapping(category: string): category is IsekaiCategory {
  return Object.hasOwn(CATEGORY_TO_BIGGENRE, category as IsekaiCategory);
}

Prevention

When it happens

Trigger: A maintainer adds a new IsekaiCategory value to types/ranking.ts without adding the corresponding case in getIsekaiSearchParams; new code calls getIsekaiSearchParams directly, bypassing parseIsekaiRankingType.

Common situations: Maintainer extends the enum and forgets the switch arm; refactor introduces a second call site that skips validation.

Related errors


AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12). Data as JSON: /api/errors/6bd48d2f2069b899. Report an issue: GitHub.