DIYgod/RSSHub · error · InvalidParameterError
Invalid Syosetu subsite.\nValid subsites are: yomou, noc, mn
Error message
Invalid Syosetu subsite.\nValid subsites are: yomou, noc, mnlt, mid
What it means
Thrown by syosetu/search.ts:120 as an InvalidParameterError in the default arm of createNovelSearchBuilder, when `sub` is not 'yomou' (handled earlier, returns a general SearchBuilder) and not one of the R18 cases {noc, mnlt, mid}. CRITICAL footgun: the SyosetuSub enum in types/search.ts has only FOUR members (YOMOU, NOCTURNE, MOONLIGHT, MIDNIGHT) and does NOT include MOONLIGHT_BL — so /syosetu/search/mnlt-bl/... throws here, even though mnlt-bl is a valid subsite in the rankingr18 route. The same-named enum diverges between files.
Source
Thrown at lib/routes/syosetu/search.ts:120
const r18Params = { ...searchParams };
switch (sub) {
case SyosetuSub.NOCTURNE:
r18Params.nocgenre = R18Site.Nocturne;
break;
case SyosetuSub.MOONLIGHT:
// If either 女性向け/BL is chosen, nocgenre will be in query string
// If no specific genre selected, include both
if (!r18Params.nocgenre) {
r18Params.nocgenre = [R18Site.MoonLight, R18Site.MoonLightBL].join('-') as Join<R18Site>;
}
break;
case SyosetuSub.MIDNIGHT:
r18Params.nocgenre = R18Site.Midnight;
break;
default:
throw new InvalidParameterError('Invalid Syosetu subsite.\nValid subsites are: yomou, noc, mnlt, mid');
}
return new SearchBuilderR18(r18Params, new NarouNovelFetch());
}
async function handler(ctx: Context): Promise<Data> {
const { sub, query } = ctx.req.param();
const searchUrl = `https://${sub}.syosetu.com/search/search/search.php?${query}`;
const limit = Math.min(Number(ctx.req.query('limit') ?? 40), 40);
const searchParams = mapToSearchParams(query, limit);
const builder = createNovelSearchBuilder(sub, searchParams);
const result = await builder.execute();
const items = result.values.map((novel) => ({
title: novel.title,
link: `https://${isGeneral(sub) ? 'ncode' : 'novel18'}.syosetu.com/${String(novel.ncode).toLowerCase()}`,
description: renderDescription({ novel, genreText: GenreNotation[novel.genre] }),View on GitHub (pinned to bed535e087)
Solutions
- Use yomou, noc, mnlt, or mid as the sub.
- For Moonlight BL results, use sub=mnlt and supply the nocgenre parameter in the query string.
Example fix
// before (mnlt-bl is not a valid search subsite) GET /syosetu/search/mnlt-bl/word=... // after (use mnlt + nocgenre in query) GET /syosetu/search/mnlt/word=...&nocgenre=<MoonLightBL>
Defensive patterns
Strategy: validation
Validate before calling
import { SyosetuSub } from './types/search';
// search.ts SyosetuSub is {yomou, noc, mnlt, mid} — mnlt-bl is NOT valid here.
function isValidSearchSub(sub: string): boolean {
return Object.values(SyosetuSub).includes(sub as SyosetuSub);
} Type guard
import { SyosetuSub } from './types/search';
function isSearchSub(sub: string): sub is SyosetuSub {
return ['yomou', 'noc', 'mnlt', 'mid'].includes(sub);
} Prevention
- Use yomou, noc, mnlt, or mid for the search route — never mnlt-bl.
- For Moonlight BL, use sub=mnlt and pass nocgenre in the query string.
- Remember the SyosetuSub enum diverges between search.ts and ranking-r18.ts.
When it happens
Trigger: /syosetu/search/<sub>/<query> with sub not in {yomou, noc, mnlt, mid}: specifically mnlt-bl throws; full names like 'nocturne' or 'moonlight'; typos.
Common situations: Trying to search Moonlight BL via this route (not supported — you must use mnlt and pass nocgenre in the query string); assuming mnlt-bl works here because it works in rankingr18; using the display name.
Related errors
- Invalid subsite: ${sub}
- Invalid isekai ranking type: ${type}
- Invalid 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/c1000bdceb867d3b.
Report an issue: GitHub.