{"record":{"id":"b4173d79b77c26b8","repo":"DIYgod/RSSHub","slug":"invalid-language-b4173d","errorCode":null,"errorMessage":"Invalid language","messagePattern":"Invalid language","errorType":"validation","errorClass":"InvalidParameterError","httpStatus":null,"severity":"warning","filePath":"lib/routes/myfigurecollection/index.tsx","lineNumber":47,"sourceCode":"    radar: [\n        {\n            source: ['zh.myfigurecollection.net/browse', 'zh.myfigurecollection.net/'],\n        },\n    ],\n    name: '圖片',\n    maintainers: ['nczitzk'],\n    handler,\n    url: 'zh.myfigurecollection.net/browse',\n    description: `| 每日圖片 | 每週圖片 | 每月圖片 |\n| -------- | -------- | -------- |\n| potd     | potw     | potm     |`,\n};\n\nasync function handler(ctx) {\n    const language = ctx.req.param('language') ?? '';\n    const category = ctx.req.param('category') ?? 'figure';\n    if (language && !isValidHost(language)) {\n        throw new InvalidParameterError('Invalid language');\n    }\n\n    const rootUrl = `https://${language === 'en' || language === '' ? '' : `${language}.`}myfigurecollection.net`;\n    const currentUrl = `${rootUrl}/${Object.hasOwn(shortcuts, category) ? shortcuts[category] : category}`;\n\n    const response = await got({\n        method: 'get',\n        url: currentUrl,\n    });\n\n    const $ = load(response.data);\n\n    let items = $('.item-icon, .picture-icon')\n        .slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 25)\n        .toArray()\n        .map((item): DataItem => {\n            const $item = $(item).find('a');\n","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/myfigurecollection/index.tsx#L29-L65","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nif (language && !isValidHost(language)) {\n    throw new InvalidParameterError('Invalid language');\n}\n\n// after — shared allowlist with the activity route\nimport { MFC_LANGUAGES } from './languages';\nif (language && !MFC_LANGUAGES.includes(language.toLowerCase())) {\n    throw new InvalidParameterError(`Invalid language '${language}'. Supported: ${MFC_LANGUAGES.join(', ')}`);\n}","handlingStrategy":"validation","validationCode":"// Share a constant with the activity route\nimport { MFC_LANGUAGES } from './languages';\nconst language = (ctx.req.param('language') ?? '').toLowerCase();\nif (language && !MFC_LANGUAGES.includes(language)) {\n    throw new InvalidParameterError(`Invalid language '${language}'. Supported: ${MFC_LANGUAGES.filter(Boolean).join(', ')}`);\n}","typeGuard":"function isMfcLanguage(l: string): boolean {\n    const allowed = new Set(['', 'en', 'de', 'es', 'fi', 'fr', 'it', 'ja', 'nl', 'no', 'pl', 'pt', 'ru', 'sv', 'zh']);\n    return allowed.has(l.toLowerCase());\n}","tryCatchPattern":null,"preventionTips":["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)."],"tags":["validation","language","hostname","myfigurecollection","parameter","duplicate-guard"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}