{"record":{"id":"56b957a76b358943","repo":"DIYgod/RSSHub","slug":"language-parameter-is-not-valid-please-use-one-of","errorCode":null,"errorMessage":"Language parameter is not valid. Please use one of the following: ${SUPPORTED_LANGUAGES.join(', ')}","messagePattern":"Language parameter is not valid\\. Please use one of the following: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"warning","filePath":"lib/routes/kurogames/wutheringwaves/news.ts","lineNumber":53,"sourceCode":"|----------|--------------|\n| English  | en           |\n| 日本語    | jp           |\n| 한국어     | kr           |\n| 简体中文   | zh (default) |\n| 繁體中文   | zh-tw        |\n| Español  | es           |\n| Français | fr           |\n| Deutsch  | de           |\n    `,\n    async handler(ctx) {\n        const limitParam = ctx.req.query(Parameter.Limit);\n        const languageParam = ctx.req.param(Parameter.Language);\n\n        const limit = parseInteger(limitParam, 30);\n        const language = languageParam || Language.Chinese;\n\n        if (!isValidLanguage(language)) {\n            throw new TypeError(`Language parameter is not valid. Please use one of the following: ${SUPPORTED_LANGUAGES.join(', ')}`);\n        }\n\n        const articles = await fetchArticles(language);\n        const filteredArticles = articles.filter((a) => a.articleType !== 0).slice(0, limit);\n\n        const item = await Promise.all(\n            filteredArticles.map((article) => {\n                const contentUrl = getArticleContentLink(language, article.articleId);\n                const item: DataItem = {\n                    title: article.articleTitle,\n                    pubDate: timezone(parseDate(article.createTime), 8),\n                    link: getArticleLink(language, article.articleId),\n                };\n\n                return cache.tryGet(`wutheringwaves:${language}:${article.articleId}`, async () => {\n                    const articleDetails = await ofetch<Article>(contentUrl, { query: { t: Date.now() } });\n                    // Article content may not always be available, e.g: https://wutheringwaves.kurogames.com/zh-tw/main/news/detail/2596\n                    const articleContent = articleDetails.articleContent ?? '';","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/kurogames/wutheringwaves/news.ts#L35-L71","documentation":"Thrown by the kurogames Wuthering Waves (鸣潮) news handler as a TypeError when the language path param fails isValidLanguage(). Supported languages come from SUPPORTED_LANGUAGES (en, jp, kr, zh, zh-tw, es, fr, de per the route description). The error message lists all valid codes so the caller can correct the input.","triggerScenarios":"Request to /kurogames/wutheringwaves/news/<lang> where <lang> is not in SUPPORTED_LANGUAGES — e.g. /news/english, /news/zhs, /news/us, or a typo. Omitting the param is safe (defaults to Language.Chinese).","commonSituations":"User supplies a full language name instead of the code; uses an ISO code not in the set (e.g. 'zh-cn' instead of 'zh', 'ja' instead of 'jp'); typo; case mismatch if isValidLanguage is case-sensitive.","solutions":["Use one of the documented codes: en, jp, kr, zh, zh-tw, es, fr, de","Omit the param entirely to get the default (zh)","If you need a new language, add it to SUPPORTED_LANGUAGES and Language enum in lib/routes/kurogames/wutheringwaves/constants.ts","Verify whether isValidLanguage is case-sensitive and match the case of the listed codes"],"exampleFix":"// before\nconst language = languageParam || Language.Chinese;\nif (!isValidLanguage(language)) {\n    throw new TypeError(`Language parameter is not valid. Please use one of the following: ${SUPPORTED_LANGUAGES.join(', ')}`);\n}\n// after — normalize case before rejecting\nconst language = (languageParam || Language.Chinese).toLowerCase();\nif (!isValidLanguage(language)) {\n    throw new TypeError(`Language '${languageParam}' is not valid. Use one of: ${SUPPORTED_LANGUAGES.join(', ')}`);\n}","handlingStrategy":"type-guard","validationCode":"import { SUPPORTED_LANGUAGES } from './constants';\nfunction isValidLang(code: string | undefined): boolean {\n  return code === undefined || SUPPORTED_LANGUAGES.includes(code as any);\n}\nif (!isValidLang(ctx.req.param(Parameter.Language))) {\n  return ctx.json({ error: `language must be one of ${SUPPORTED_LANGUAGES.join(', ')}` }, 400);\n}","typeGuard":"import { SUPPORTED_LANGUAGES, Language } from './constants';\nfunction isSupportedLanguage(v: unknown): v is Language {\n  return typeof v === 'string' && (SUPPORTED_LANGUAGES as readonly string[]).includes(v);\n}","tryCatchPattern":"try { return await route.handler(ctx); }\ncatch (e) {\n  if (e instanceof TypeError && /Language parameter/.test(e.message)) {\n    return ctx.json({ error: e.message, allowed: SUPPORTED_LANGUAGES }, 400);\n  }\n  throw e;\n}","preventionTips":["Normalize case (lowercase) before validation","Default the param so omission is always valid","Expose the supported list in both the error and route description","Use a typed enum (Language) so new codes are added in one place"],"tags":["validation","parameter","i18n","enum"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}