DIYgod/RSSHub · warning

Bad category. See <a href="https://docs.rsshub.app/routes/go

Error message

Bad category. See <a href="https://docs.rsshub.app/routes/government#hu-bei-ruan-jian-hang-ye-xie-hui">docs</a>

What it means

Thrown by the Hubei Software Industry Association route (deprecated) when :caty is not a config key. The config holds only titles (e.g. rjzj, txrz, zxjsfw, shzzdj, xyzl, xhkw) and the URL is built as /<caty>/index.jhtml, so a miss throws before the request.

Source

Thrown at lib/routes-deprecated/gov/hubei/hbsia.js:61

    yyal: { title: '应用案例' },
    xgxzi: { title: 'ITSS相关下载' },

    xydjpj: { title: '信用等级评价' },
    kjcgpj: { title: '科技成果评价' },
    dbpc: { title: '等保评测' },
    rjzj: { title: '软件造价' },
    txrz: { title: '体系认证' },
    zxjsfw: { title: '专项技术服务' },

    shzzdj: { title: '社会组织党建' },
    xyzl: { title: '行业自律' },
    xhkw: { title: '协会刊物' },
};

module.exports = async (ctx) => {
    const cfg = config[ctx.params.caty];
    if (!cfg) {
        throw new Error('Bad category. See <a href="https://docs.rsshub.app/routes/government#hu-bei-ruan-jian-hang-ye-xie-hui">docs</a>');
    }

    const current_url = url.resolve(root_url, `/${ctx.params.caty}/index.jhtml`);
    const response = await got({
        method: 'get',
        url: current_url,
    });
    const $ = cheerio.load(response.data);
    const list = $('div.i_content li')
        .slice(0, 20)
        .map((_, item) => {
            item = $(item);
            const a = item.find('a[href]');
            const span = item.find('span');
            return {
                title: a.text(),
                link: url.resolve(current_url, a.attr('href')),
                pubDate: parseDate(span.text(), 'YYYY-MM-DD'),

View on GitHub (pinned to bed535e087)

Solutions

  1. Use a documented slug such as rjzj, txrz, zxjsfw, shzzdj, xyzl, or xhkw.
  2. Check the config map at the top of lib/routes-deprecated/gov/hubei/hbsia.js.
  3. If the section 404s on the source site, report it rather than substituting a slug.

Example fix

// before
GET /gov/hubei/hbsia/ruanjian   // not a key
// after
GET /gov/hubei/hbsia/rjzj         // 软件造价
Defensive patterns

Strategy: validation

Validate before calling

const VALID = ['rjzj', 'txrz', 'zxjsfw', 'shzzdj', 'xyzl', 'xhkw'];
if (!VALID.includes(ctx.params.caty)) throw new Error(`Invalid caty. Valid: ${VALID.join(', ')}`);

Type guard

const isCaty = (v: string): v is 'rjzj' | 'txrz' | 'zxjsfw' | 'shzzdj' | 'xyzl' | 'xhkw' =>
  ['rjzj','txrz','zxjsfw','shzzdj','xyzl','xhkw'].includes(v);

Try / catch

try { await fetch(route); }
catch (e) { if (/Bad category/.test(e.message)) promptSlug(); else throw e; }

Prevention

When it happens

Trigger: Request with a category slug not in the config map; the throw fires at config[ctx.params.caty].

Common situations: Slug typo, or the association site dropping a section so its slug was removed from config. Because the slug is also interpolated into the URL, even a near-miss would 404 downstream if the guard were absent.

Related errors


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