DIYgod/RSSHub · warning · InvalidParameterError
Invalid language
Error message
Invalid language
What it means
Thrown by the MyFigureCollection main (pictures) route when the :language parameter is non-empty and fails the same isValidHost regex used in the activity route. The language becomes a subdomain of myfigurecollection.net, so it must be a syntactically valid DNS label. This is the identical guard to error 758 but on the sibling route.
Source
Thrown at lib/routes/myfigurecollection/index.tsx:47
radar: [
{
source: ['zh.myfigurecollection.net/browse', 'zh.myfigurecollection.net/'],
},
],
name: '圖片',
maintainers: ['nczitzk'],
handler,
url: 'zh.myfigurecollection.net/browse',
description: `| 每日圖片 | 每週圖片 | 每月圖片 |
| -------- | -------- | -------- |
| potd | potw | potm |`,
};
async function handler(ctx) {
const language = ctx.req.param('language') ?? '';
const category = ctx.req.param('category') ?? 'figure';
if (language && !isValidHost(language)) {
throw new InvalidParameterError('Invalid language');
}
const rootUrl = `https://${language === 'en' || language === '' ? '' : `${language}.`}myfigurecollection.net`;
const currentUrl = `${rootUrl}/${Object.hasOwn(shortcuts, category) ? shortcuts[category] : category}`;
const response = await got({
method: 'get',
url: currentUrl,
});
const $ = load(response.data);
let items = $('.item-icon, .picture-icon')
.slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 25)
.toArray()
.map((item): DataItem => {
const $item = $(item).find('a');
View on GitHub (pinned to bed535e087)
Solutions
- Use a supported two-letter code (en, de, es, fr, ja, zh, etc.) or omit the parameter for English.
- Share a single allowed-language constant between this route and the activity route to keep them in sync.
- Add a DNS-resolution or HTTP-probe fallback if you want to support unknown-but-valid subdomains.
Example fix
// before
if (language && !isValidHost(language)) {
throw new InvalidParameterError('Invalid language');
}
// after — shared allowlist with the activity route
import { MFC_LANGUAGES } from './languages';
if (language && !MFC_LANGUAGES.includes(language.toLowerCase())) {
throw new InvalidParameterError(`Invalid language '${language}'. Supported: ${MFC_LANGUAGES.join(', ')}`);
} Defensive patterns
Strategy: validation
Validate before calling
// Share a constant with the activity route
import { MFC_LANGUAGES } from './languages';
const language = (ctx.req.param('language') ?? '').toLowerCase();
if (language && !MFC_LANGUAGES.includes(language)) {
throw new InvalidParameterError(`Invalid language '${language}'. Supported: ${MFC_LANGUAGES.filter(Boolean).join(', ')}`);
} Type guard
function isMfcLanguage(l: string): boolean {
const allowed = new Set(['', 'en', 'de', 'es', 'fi', 'fr', 'it', 'ja', 'nl', 'no', 'pl', 'pt', 'ru', 'sv', 'zh']);
return allowed.has(l.toLowerCase());
} Prevention
- Extract the valid-language list into a shared module so both MFC routes stay in sync.
- Prefer an explicit allowlist over the hostname regex for clearer errors.
- Normalize case before checking.
- Document that an empty language segment means English (the default).
When it happens
Trigger: Same as 758: a language value containing dots, underscores, spaces, non-ASCII, or exceeding 63 characters. The default (empty string → en) never triggers this; only an explicitly-supplied invalid value does.
Common situations: User passes an IETF-style tag like 'zh-Hant' (hyphenated is allowed by the regex but may not resolve as a real subdomain). User passes a full URL or hostname fragment. User passes a numeric-only code that happens to pass the regex but isn't a real MFC subdomain.
Related errors
- Invalid language
- Invalid language
- Invalid language
- Bad timeRange range. See <a href="https://docs.rsshub.app/ro
- Bad parameter. See <a href="https://docs.rsshub.app/routes/g
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/b4173d79b77c26b8.
Report an issue: GitHub.