DIYgod/RSSHub · error · InvalidParameterError
Invalid subsite: ${sub}
Error message
Invalid subsite: ${sub} What it means
Thrown by syosetu/ranking-r18.ts:167 as an InvalidParameterError when the `sub` path param is not a key of syosetuSubToNocgenre (types/ranking-r18.ts:25). Valid R18 subsites: noc (Nocturne), mnlt (Moonlight), mnlt-bl (Moonlight BL), mid (Midnight). NOTE the footgun: mnlt-bl IS valid here because ranking-r18.ts's SyosetuSub enum includes MOONLIGHT_BL, but search.ts's SyosetuSub enum does NOT — the same-named enum has different members across files. The check runs AFTER parseRankingType, so an invalid `type` throws first.
Source
Thrown at lib/routes/syosetu/ranking-r18.ts:167
const rankingUrl = `${baseUrl}/rank/list/type/${type}`;
const api = new NarouNovelFetch();
const limit = Math.min(Number(ctx.req.query('limit') ?? 300), 300);
const { period, novelType } = parseRankingType(type);
const searchParams: SearchParams = {
gzip: 5,
lim: limit,
order: periodToOrder[period],
};
// TOTAL: Skip type filter to get all types combined
if (novelType !== NovelType.TOTAL) {
searchParams.type = novelType;
}
if (!Object.hasOwn(syosetuSubToNocgenre, sub)) {
throw new InvalidParameterError(`Invalid subsite: ${sub}`);
}
const nocgenre = syosetuSubToNocgenre[sub];
const builder = new SearchBuilderR18(searchParams, api).r18Site(nocgenre);
const result = await builder.execute();
const items = result.values.map((novel, index) => ({
title: `#${index + 1} ${novel.title}`,
link: `https://novel18.syosetu.com/${String(novel.ncode).toLowerCase()}`,
description: renderDescription({ novel }),
author: novel.writer,
category: novel.keyword.split(/[\s/\u{FF0F}]/u).filter(Boolean),
}));
return {
title: `小説家になろう (${sub}) - ${getRankingTitle(type, limit)}`,
link: rankingUrl,
item: items as DataItem[],View on GitHub (pinned to bed535e087)
Solutions
- Use noc, mnlt, mnlt-bl, or mid (lowercase, hyphenated exactly where shown).
- Remember mnlt-bl is valid ONLY in the rankingr18 route — not in the search route.
Example fix
// before GET /syosetu/rankingr18/mnltbl/daily_total // after GET /syosetu/rankingr18/mnlt-bl/daily_total
Defensive patterns
Strategy: validation
Validate before calling
import { syosetuSubToNocgenre } from './types/ranking-r18';
function isValidR18Sub(sub: string): boolean {
return Object.hasOwn(syosetuSubToNocgenre, sub);
} Type guard
import { SyosetuSub } from './types/ranking-r18';
const VALID_R18_SUBS = Object.values(SyosetuSub); // noc, mnlt, mnlt-bl, mid
function isR18Sub(sub: string): sub is SyosetuSub {
return (VALID_R18_SUBS as readonly string[]).includes(sub);
} Prevention
- Use noc, mnlt, mnlt-bl, or mid — exactly hyphenated where shown.
- Remember mnlt-bl is valid ONLY in rankingr18, not in the search route.
- Do not assume the subsite code set is identical across syosetu routes.
When it happens
Trigger: /syosetu/rankingr18/<sub>/<type> with sub not in {noc, mnlt, mnlt-bl, mid}: typos like 'mnltbl' (missing hyphen), 'nocturne', 'moonlight', or 'bl' alone.
Common situations: Using the full site name instead of the code; forgetting the hyphen in mnlt-bl; assuming the subsite code set is identical across all syosetu routes.
Related errors
- Invalid Syosetu subsite.\nValid subsites are: yomou, noc, mn
- Invalid ranking type: ${type}
- Invalid isekai ranking type: ${type}
- Invalid general ranking type: ${type}
- Invalid genre ranking type: ${type}
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/9550fe1a74e06242.
Report an issue: GitHub.