DIYgod/RSSHub · error · InvalidParameterError
Invalid channel name
Error message
Invalid channel name
What it means
The 21财经 channel route fetches a remote webMenu.json from static.21jingji.com and verifies the requested channel `name` is a key in that live menu before composing the API URL. InvalidParameterError is thrown if the channel is not present, because the subsequent API call would be meaningless.
Source
Thrown at lib/routes/21caijing/channel.ts:57
}
return result;
};
export const handler = async (ctx: Context): Promise<Data> => {
const { name = '热点' } = ctx.req.param();
const limit = Number(ctx.req.query('limit') ?? '30');
const domain = 'm.21jingji.com';
const baseUrl = `https://${domain}`;
const staticBaseUrl = 'https://static.21jingji.com';
const menuUrl: string = new URL('m/webMenu.json', staticBaseUrl).href;
const menuResponse = await ofetch(menuUrl);
const menu = processMenu(menuResponse);
if (!menu.hasOwnProperty(name)) {
throw new InvalidParameterError('Invalid channel name');
}
const currentChannel = menu[name];
const apiUrl: string = new URL(currentChannel.apiUrl, baseUrl).href;
const targetUrl: string = new URL(`#/${currentChannel.url}`, baseUrl).href;
const authUrl: string = new URL('reader/cbhChannelAuth', baseUrl).href;
const targetResponse = await ofetch(targetUrl);
const $: CheerioAPI = load(targetResponse);
const language: string = $('html').attr('lang') ?? 'zh-CN';
const authResponse = await ofetch(authUrl, {
method: 'POST',
responseType: 'json',
});
const response = await ofetch(apiUrl, {View on GitHub (pinned to bed535e087)
Solutions
- Open https://static.21jingji.com/m/webMenu.json and copy an existing key verbatim.
- Fall back to the default by omitting the segment (defaults to '热点').
- If the menu endpoint itself moved, report it to maintainers — the URL may need updating.
Example fix
// before /21caijing/channel/hotnews // not a key in webMenu.json // after /21caijing/channel/热点 // or omit the segment
Defensive patterns
Strategy: try-catch
Validate before calling
// Cannot be fully pre-validated without fetching webMenu.json,
// but you can pre-flight it:
async function channelExists(name) {
const menu = await ofetch('https://static.21jingji.com/m/webMenu.json');
return Object.prototype.hasOwnProperty.call(processMenu(menu), name);
} Type guard
function isInMenu(menu, name): name is string {
return typeof name === 'string' && Object.prototype.hasOwnProperty.call(menu, name);
} Try / catch
try {
return await build21caijingFeed(name);
} catch (e) {
if (e instanceof InvalidParameterError && /Invalid channel name/.test(e.message)) {
// refresh the menu once and retry, else fall back to default '热点'
return await build21caijingFeed('热点');
}
throw e;
} Prevention
- Cache webMenu.json with a short TTL so stale channel names surface quickly.
- Default to '热点' when user input is unverified.
- Watch for InvalidParameterError specifically and degrade rather than fail the whole feed.
When it happens
Trigger: Calling /21caijing/channel/:name with a value that is not a property of the fetched m/webMenu.json — a typo, a renamed channel, or a channel the app retired.
Common situations: The menu changed upstream (channel renamed/removed); copy-pasting a stale name; the default '热点' no longer being present after a redesign.
Related errors
- Bad timeRange range. See <a href="https://docs.rsshub.app/ro
- Bad parameter. See <a href="https://docs.rsshub.app/routes/g
- Invalid city
- This category does not exist. Please refer to the documentat
- Invalid category Id: ${categoryId}
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/dcacfa9990e5838c.
Report an issue: GitHub.