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

  1. Use a supported two-letter code (en, de, es, fr, ja, zh, etc.) or omit the parameter for English.
  2. Share a single allowed-language constant between this route and the activity route to keep them in sync.
  3. 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

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


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