DIYgod/RSSHub · warning · InvalidParameterError

Invalid language

Error message

Invalid language

What it means

Thrown by the Kyodo News route when the :language path parameter is not one of 'china' (simplified Chinese) or 'tchina' (traditional Chinese). Unlike most language codes, these are site/subdomain selectors for Kyodo's Chinese-edition domains (china.kyodonews.net / tchina.kyodonews.net). An invalid value would produce a non-existent subdomain.

Source

Thrown at lib/routes/kyodonews/index.tsx:50

        {
            source: ['tchina.kyodonews.net/news/:keyword', 'tchina.kyodonews.net/'],
            target: '/tchina/:keyword?',
        },
    ],
    name: '最新报道',
    maintainers: ['Rongronggg9'],
    handler,
    description:
        '`keyword` 为关键词,由于共同网有许多关键词并不在主页列出,此处不一一列举,可从关键词页的 URL 的最后一级路径中提取。如 `日中关系` 的关键词页 URL 为 `https://china.kyodonews.net/news/japan-china_relationship`, 则将 `japan-china_relationship` 填入 `keyword`。特别地,当填入 `rss` 时,将从共同网官方 RSS 中抓取文章;略去时,将从首页抓取最新报道 (注意:首页更新可能比官方 RSS 稍慢)。',
};

async function handler(ctx) {
    const language = ctx.req.param('language') ?? 'china';
    const keyword = ctx.req.param('keyword') === 'RSS' ? 'rss' : (ctx.req.param('keyword') ?? '');

    // raise error for invalid languages
    if (!['china', 'tchina'].includes(language)) {
        throw new InvalidParameterError('Invalid language');
    }

    const rootUrl = `https://${language}.kyodonews.net`;
    const currentUrl = `${rootUrl}/${keyword ? (keyword === 'rss' ? 'list/feed/rss4news' : `news/${keyword}`) : ''}`;

    let response;
    try {
        response = await got(currentUrl);
    } catch (error) {
        const err = error as { response?: { statusCode: number } };
        throw err.response && err.response.statusCode === 404 ? new InvalidParameterError('Invalid keyword') : error;
    }

    const $ = load(response.data, { xmlMode: keyword === 'rss' });

    let title, description, image, items;
    image = `https://${language}-kyodo.ismcdn.jp/common/images/apple-touch-icon-180x180.png`;

View on GitHub (pinned to bed535e087)

Solutions

  1. Use only 'china' or 'tchina' as the language segment (or omit it — 'china' is the default).
  2. Normalize to lowercase and include valid values in the error message.
  3. Note that an invalid keyword (vs language) produces a separate 'Invalid keyword' error from the 404 handler, so this check is specifically for the language segment.

Example fix

// before
if (!['china', 'tchina'].includes(language)) {
    throw new InvalidParameterError('Invalid language');
}

// after
const validLangs = ['china', 'tchina'];
if (!validLangs.includes(language.toLowerCase())) {
    throw new InvalidParameterError(`Invalid language '${language}'. Supported: ${validLangs.join(', ')} (Simplified / Traditional Chinese)`);
}
Defensive patterns

Strategy: validation

Validate before calling

const VALID_LANGS = ['china', 'tchina'] as const;
type KyodoLang = typeof VALID_LANGS[number];
function isKyodoLang(s: string): s is KyodoLang {
    return (VALID_LANGS as readonly string[]).includes(s.toLowerCase());
}
const language = ctx.req.param('language') ?? 'china';
if (!isKyodoLang(language)) {
    throw new InvalidParameterError(`Invalid language '${language}'. Supported: ${VALID_LANGS.join(', ')} (Simplified/Traditional Chinese only)`);
}

Type guard

function isKyodoLang(s: string): s is 'china' | 'tchina' {
    return ['china', 'tchina'].includes(s.toLowerCase());
}

Prevention

When it happens

Trigger: Calling /kyodonews/en/... or /kyodonews/ja/... — Kyodo News' English/Japanese editions are not supported by this route. Also fires for typos like 'chian' or 'China' (case-sensitive, no normalization).

Common situations: User assumes standard ISO language codes work. User passes uppercase. A user wants the Japanese domestic service which is a different site entirely and not covered here.

Related errors


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