DIYgod/RSSHub · error · InvalidParameterError
Invalid ranking type: ${type}
Error message
Invalid ranking type: ${type} What it means
Thrown by parseRankingType (syosetu/ranking-r18.ts:132) as an InvalidParameterError when the R18 ranking `type` (format period_novelType) has an invalid component. CRITICAL difference from the general ranking: the R18 RankingPeriod enum (types/ranking-r18.ts:10) EXCLUDES 'total' — valid R18 periods are daily, weekly, monthly, quarter, yearly only. novelType (NovelType) is the same: total, t, r, er. Reached via /syosetu/rankingr18/<sub>/<type>. The R18 enum is file-local and looks nearly identical to the general one, which is the main footgun.
Source
Thrown at lib/routes/syosetu/ranking-r18.ts:132
},
{
source: ['mnlt.syosetu.com/rank/bllist/type/:type'],
target: '/rankingr18/mnlt-bl/:type',
},
...getBest5RadarItems(),
],
};
function parseRankingType(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 ranking type: ${type}`);
}
return {
period: periodStr as RankingPeriod,
novelType: novelTypeStr as NovelType,
};
}
function getRankingTitle(type: string, limit: number): string {
const { period, novelType } = parseRankingType(type);
return `${periodToJapanese[period]}${novelTypeToJapanese[novelType]}ランキング BEST${limit}`;
}
async function handler(ctx: Context): Promise<Data> {
const { sub, type } = ctx.req.param();
const baseUrl = `https://${sub === SyosetuSub.MOONLIGHT_BL ? SyosetuSub.MOONLIGHT : sub}.syosetu.com`;
const rankingUrl = `${baseUrl}/rank/list/type/${type}`;
const api = new NarouNovelFetch();View on GitHub (pinned to bed535e087)
Solutions
- Use a valid R18 period — daily, weekly, monthly, quarter, or yearly — never 'total'.
- Keep the <period>_<novelType> order, with novelType in {total, t, r, er}.
Example fix
// before (total period is invalid for R18) GET /syosetu/rankingr18/noc/total_total // after GET /syosetu/rankingr18/noc/daily_total
Defensive patterns
Strategy: validation
Validate before calling
import { RankingPeriod, NovelType } from './types/ranking-r18';
// R18 RankingPeriod EXCLUDES 'total' — do not import the general one by mistake.
const PERIODS = Object.values(RankingPeriod);
const NOVEL_TYPES = Object.values(NovelType);
function isValidR18Type(type: string): boolean {
const [p, n] = type.split('_', 2);
return PERIODS.includes(p as RankingPeriod)
&& NOVEL_TYPES.includes(n as NovelType);
} Type guard
function isR18RankingType(type: string): boolean {
const [p, n] = type.split('_', 2);
return ['daily','weekly','monthly','quarter','yearly'].includes(p) // NO 'total'
&& ['total','t','r','er'].includes(n);
} Prevention
- Never use 'total' as the period in an R18 ranking URL — it is only valid in the general ranking.
- Remember the R18 RankingPeriod enum is file-local and a strict subset of the general one.
- Keep the <period>_<novelType> order.
When it happens
Trigger: Using 'total' as the period (e.g. total_t or total_total) — not supported on R18 sites; wrong segment order (t_daily); unknown novelType; missing the novelType segment.
Common situations: Copying a general-ranking URL (/ranking/list/total_total) into the r18 route; assuming the two RankingPeriod enums are the same.
Related errors
- Invalid isekai ranking type: ${type}
- Invalid subsite: ${sub}
- Invalid general ranking type: ${type}
- Invalid genre ranking type: ${type}
- Invalid ranking type: ${type}
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/5ce883708931db5e.
Report an issue: GitHub.