DIYgod/RSSHub · error · InvalidParameterError
Invalid language parameter. Use "en" or "zh".
Error message
Invalid language parameter. Use "en" or "zh".
What it means
InvalidParameterError thrown by the XJTLU news handler when ctx.req.param('lang') is neither 'en' nor 'zh' (the only two language editions the site supports). It guards the URL before it is built, because baseUrl embeds the lang segment directly.
Source
Thrown at lib/routes/xjtlu/news.ts:55
zh: { name: '校园与社区', path: 'news_category/topictopic1679' },
},
about: {
en: { name: 'About XJTLU', path: 'news/about-xjtlu' },
zh: { name: '要闻聚焦', path: 'news_category/%E8%A6%81%E9%97%BB%E8%81%9A%E7%84%A6' },
},
stories: {
en: { name: 'XJTLU Stories', path: 'news/xjtlu-stories' },
zh: { name: '招生专区', path: 'news_category/topictopic4683' },
},
};
const handler = async (ctx) => {
const lang = ctx.req.param('lang') ?? 'en';
const category = ctx.req.param('category') ?? 'all';
// Validate language parameter
if (lang !== 'en' && lang !== 'zh') {
throw new InvalidParameterError('Invalid language parameter. Use "en" or "zh".');
}
// Validate category parameter
if (!Object.hasOwn(categories, category)) {
throw new InvalidParameterError(`Invalid category: ${category}. Please refer to the category table in the documentation.`);
}
// Build the list URL based on category
const baseUrl = `https://www.xjtlu.edu.cn/${lang}`;
const categoryPath = categories[category][lang].path;
const listUrl = `${baseUrl}/${categoryPath}`;
// Fetch the news list page
const response = await ofetch(listUrl);
const $ = load(response);
// Extract article cards from the page
const list = $('.card-group-3 .card.up-down-card, .content .card.up-down-card')View on GitHub (pinned to bed535e087)
Solutions
- Use exactly 'en' or 'zh' for the lang path segment.
- If case-insensitivity is desired, normalize: const lang = (ctx.req.param('lang') ?? 'en').toLowerCase(); before the check.
- Document the allowed values prominently in the route description.
Example fix
// before
const lang = ctx.req.param('lang') ?? 'en';
if (lang !== 'en' && lang !== 'zh') {
throw new InvalidParameterError('Invalid language parameter. Use "en" or "zh".');
}
// after — accept case variants while still rejecting unsupported locales
const lang = (ctx.req.param('lang') ?? 'en').toLowerCase();
if (lang !== 'en' && lang !== 'zh') {
throw new InvalidParameterError(`Invalid language parameter "${lang}". Use "en" or "zh".`);
} Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED_LANGS = new Set(['en', 'zh']);
function normalizeLang(raw: string | undefined): 'en' | 'zh' {
const lang = (raw ?? 'en').toLowerCase();
if (!SUPPORTED_LANGS.has(lang)) {
throw new InvalidParameterError(`Invalid language "${raw}". Use "en" or "zh".`);
}
return lang as 'en' | 'zh';
} Type guard
function isXjtluLang(value: string): value is 'en' | 'zh' {
return value === 'en' || value === 'zh';
} Prevention
- Normalize input case before validating to tolerate 'EN'/'ZH'.
- Document the two accepted values in the route description and example.
- Use a Set for the allow-list to scale if locales are added.
When it happens
Trigger: A request to /xjtlu/news/:lang/:category where lang is anything other than 'en' or 'zh' (e.g. 'fr', 'EN ' with whitespace, 'english', or a typo). The check runs before any network call.
Common situations: Caller copied an unsupported locale; integrator assumed case-insensitivity (route is case-sensitive, only lowercase 'en'/'zh' pass); mistyped the language segment.
Related errors
- Invalid category: ${category}. Please refer to the category
- Invalid rank type
- Invalid type: ${type}. Supported types: ${Object.keys(typeMa
- Unknown region: ${region}
- Unknown category for ${region}: ${category}
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/2f18ad2cb5fbaac9.
Report an issue: GitHub.