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

  1. Use exactly 'en' or 'zh' for the lang path segment.
  2. If case-insensitivity is desired, normalize: const lang = (ctx.req.param('lang') ?? 'en').toLowerCase(); before the check.
  3. 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

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


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