DIYgod/RSSHub · error · InvalidParameterError

Invalid general ranking type: ${type}

Error message

Invalid general ranking type: ${type}

What it means

Thrown by parseGeneralRankingType (syosetu/ranking.ts:192) as an InvalidParameterError when the general-list `type` (format period_novelType) has an invalid component. Valid periods (RankingPeriod): daily, weekly, monthly, quarter, yearly, total. Valid novelTypes (NovelType): total, t, r, er. Unlike the genre/isekai parsers, novelType has NO default here — it must be present. Reached via /syosetu/ranking/list/<type>.

Source

Thrown at lib/routes/syosetu/ranking.ts:192

        },
        {
            source: ['yomou.syosetu.com/rank/isekailist/type/:type'],
            target: '/ranking/isekai/:type',
        },
        ...getBest5RadarItems(),
    ],
};

function parseGeneralRankingType(type: string): { period: RankingPeriod; novelType: NovelType } {
    const [periodStr, novelTypeStr] = type.split('_', 2);

    const period = periodStr as RankingPeriod;
    const novelType = novelTypeStr as NovelType;

    const isValid = [Object.values(RankingPeriod).includes(period), Object.values(NovelType).includes(novelType)].every(Boolean);

    if (!isValid) {
        throw new InvalidParameterError(`Invalid general ranking type: ${type}`);
    }

    return { period, novelType };
}

function parseGenreRankingType(type: string): { period: RankingPeriod; genre: number; novelType: NovelType } {
    const [periodStr, genreStr, novelTypeStr = NovelType.TOTAL] = type.split('_', 3);

    const period = periodStr as RankingPeriod;
    const genre = Number(genreStr) as Genre;
    const novelType = novelTypeStr as NovelType;

    const isValid = [Object.values(RankingPeriod).includes(period), Object.values(Genre).includes(genre), Object.values(NovelType).includes(novelType), genre !== Genre.SonotaReplay, genre !== Genre.NonGenre].every(Boolean);

    if (!isValid) {
        throw new InvalidParameterError(`Invalid genre ranking type: ${type}`);
    }

View on GitHub (pinned to bed535e087)

Solutions

  1. Use exactly <period>_<novelType> (e.g. daily_total, weekly_r, monthly_er).
  2. Do not include a category/genre segment — use the 'genre' or 'isekai' listType for those formats.

Example fix

// before (list type takes only period_novelType, no category)
GET /syosetu/ranking/list/daily_2_total
// after
GET /syosetu/ranking/list/daily_total
Defensive patterns

Strategy: validation

Validate before calling

import { RankingPeriod, NovelType } from './types/ranking';

const PERIODS = Object.values(RankingPeriod);
const NOVEL_TYPES = Object.values(NovelType);

function isValidGeneralListType(type: string): boolean {
  const [p, n] = type.split('_', 2);
  return PERIODS.includes(p as RankingPeriod)
    && NOVEL_TYPES.includes(n as NovelType); // novelType is required for list
}

Type guard

function isGeneralRankingType(type: string): boolean {
  const [p, n] = type.split('_', 2);
  return ['daily','weekly','monthly','quarter','yearly','total'].includes(p)
    && ['total','t','r','er'].includes(n);
}

Prevention

When it happens

Trigger: Wrong segment order; unknown period or novelType; missing novelType (e.g. bare 'daily' throws); passing a three-segment genre/isekai type like daily_2_total into the list route.

Common situations: Mixing up the three sub-formats across listType values; assuming novelType is optional (it is for genre/isekai, not for list).

Related errors


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