DIYgod/RSSHub · error · Error
Failed to fetch channel data from Castbox
Error message
Failed to fetch channel data from Castbox
What it means
Thrown by the Castbox channel route when the upstream call to `https://everest.castbox.fm/data/channel/v3` returns a falsy or empty `.data` field. This is an upstream/API failure guard, not an input validation. The request itself may have succeeded (HTTP 200) but the body shape was unexpected.
Source
Thrown at lib/routes/castbox/channel.ts:65
description: `Get the channel from the Castbox channel URL. For example, the URL of the channel "Lemonade Stand" is \`https://castbox.fm/channel/Lemonade-Stand-id6776228\`, where \`Lemonade-Stand-id6776228\` is the \`channel\` parameter.
You can use the RSSHub global \`limit\` query parameter to specify the maximum number of episodes to fetch from the Castbox API (defaults to 50). For example: \`/castbox/channel/Lemonade-Stand-id6776228?limit=100\`.`,
maintainers: ['ananyatimalsina'],
handler: async (ctx) => {
const { channel } = ctx.req.param();
const cid = channel.split('-id', 2)[1];
if (!cid) {
throw new Error('Invalid channel format. Missing -id');
}
const channelParams = { cid, r: 1, raw: 1, web: 1 };
const { m: cm, n: cn, queryStr: cQuery } = getNonce(channelParams);
const channelData = await ofetch(`https://everest.castbox.fm/data/channel/v3?${cQuery}&m=${cm}&n=${cn}`);
if (!channelData?.data) {
throw new Error('Failed to fetch channel data from Castbox');
}
const chData = channelData.data;
const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit') as string) : 50;
const epParams = { cid, limit, r: 1, raw: 1, web: 1 };
const { m: em, n: en, queryStr: eQuery } = getNonce(epParams);
const epData = await ofetch(`https://everest.castbox.fm/data/episode_list/v2?${eQuery}&m=${em}&n=${en}`);
if (!epData?.data?.episode_list) {
throw new Error('Failed to fetch episode list from Castbox');
}
const episodes = epData.data.episode_list;
const items = episodes.map((ep: any) => {
let enclosure_type = 'audio/mpeg';View on GitHub (pinned to bed535e087)
Solutions
- Retry the request after a short interval — often transient.
- Verify the channel id by opening the castbox.fm URL in a browser; a deleted channel yields no data.
- If reproducing consistently across channels, the `getNonce` signing logic likely needs updating to match Castbox's current client.
- Inspect the raw `everest.castbox.fm/data/channel/v3` response (with the computed query string) to see the actual error body.
Defensive patterns
Strategy: try-catch
Type guard
function hasChannelData(r: unknown): r is { data: Record<string, unknown> } {
return typeof r === 'object' && r !== null && 'data' in r && !!r.data;
} Try / catch
try {
const channelData = await ofetch(url);
if (!channelData?.data) {
// retry once, then surface a typed error
}
} catch (e) {
throw new Error(`Castbox channel API unreachable: ${(e as Error).message}`);
} Prevention
- Verify the cid by opening the castbox.fm channel URL in a browser first.
- When the nonce algorithm changes site-wide, all channels fail at once — that is the signal to update `getNonce`.
- Log the raw response status and body during debugging; the falsy `.data` is a symptom, not a cause.
When it happens
Trigger: Castbox API returns `{}` or an error envelope without a `data` key; the cid extracted from the URL is invalid/expired and Castbox returns an empty channel; rate limiting returns a 200 with an error body; the nonce/signing in `getNonce` is rejected silently.
Common situations: Castbox changes its nonce algorithm or API contract, the channel was deleted, network proxy strips the JSON body, or transient CDN error returning HTML parsed as JSON.
Related errors
- Failed to fetch episode list from Castbox
- No posts found for the given IDs
- API error: ${response.message}
- API error: ${response.message}
- 日报数据不存在或为空
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/846a6ae23f2b3a76.
Report an issue: GitHub.