DIYgod/RSSHub · warning · Error

Invalid category. Valid options are: ${Object.keys(categorie

Error message

Invalid category. Valid options are: ${Object.keys(categories).filter(Boolean).join(', ')}

What it means

Thrown by the Hupu (虎扑) mobile site route when the `:category` path parameter is not a key in the `categories` object (which defines `nba`, `cba`, `soccer`, and `''` for home). The handler uses `Object.hasOwn(categories, c)` and throws a plain `Error` (not `InvalidParameterError`) listing valid options. Note that the empty string key `''` is valid (represents the home page), so omitting the category or passing `/` is accepted.

Source

Thrown at lib/routes/hupu/index.ts:58

                label: value.title,
                value: key,
            })),
        },
    },
    description: `::: tip
电竞分类参见 [游戏热帖](https://bbs.hupu.com/all-gg) 的对应路由 [\`/hupu/all/all-gg\`](https://rsshub.app/hupu/all/all-gg)。
:::`,
    categories: ['bbs'],
    radar: [
        {
            source: ['m.hupu.com/:category', 'm.hupu.com/'],
            target: '/:category',
        },
    ],
    handler: async (ctx): Promise<Data> => {
        const c = ctx.req.param('category') || '';
        if (!Object.hasOwn(categories, c)) {
            throw new Error('Invalid category. Valid options are: ' + Object.keys(categories).filter(Boolean).join(', '));
        }
        const category = c as keyof typeof categories;

        const rootUrl = 'https://m.hupu.com';
        const currentUrl = `${rootUrl}/${category}`;

        const response = await got({
            method: 'get',
            url: currentUrl,
        });

        const data = extractNextData<HupuApiResponse>(response.data, currentUrl);
        const { pageProps } = data.props;

        const dataKey = categories[category].data;
        if (!Object.hasOwn(pageProps, dataKey)) {
            throw new Error(`Expected '${dataKey}' property not found in pageProps for category: ${category || 'home'}`);
        }

View on GitHub (pinned to bed535e087)

Solutions

  1. Use `nba`, `cba`, `soccer`, or omit the category for the home feed.
  2. For esports content, use the separate `/hupu/all/all-gg` route as noted in the description.
  3. As a maintainer: switch to `InvalidParameterError` for HTTP 400 semantics.

Example fix

// before (broken)
// GET /hupu/football

// after (correct)
// GET /hupu/soccer
Defensive patterns

Strategy: validation

Validate before calling

const VALID_CATEGORIES = ['nba', 'cba', 'soccer', ''];
function isValidCategory(c: string): boolean {
    return VALID_CATEGORIES.includes(c);
}

Type guard

function isKnownHupuCategory(c: string): c is 'nba' | 'cba' | 'soccer' | '' {
    return c in categories;
}

Prevention

When it happens

Trigger: Requesting `/hupu/<category>` where `<category>` is not `nba`, `cba`, `soccer`, or empty. Examples: `/hupu/nhl`, `/hupu/football`, `/hupu/esports`.

Common situations: User expects esports categories (the description redirects those to `/hupu/all/all-gg`), tries a sport not covered, or uses an old category slug. The `categories.options` in route config lists valid values.

Related errors


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