DIYgod/RSSHub · error · Error
Failed to fetch episode list from Castbox
Error message
Failed to fetch episode list from Castbox
What it means
Thrown by the Castbox channel route when the episode-list endpoint `https://everest.castbox.fm/data/episode_list/v2` returns a body whose `.data.episode_list` is missing or falsy. Distinct from the channel-data guard (it fires after channel data is confirmed). Plain `Error`.
Source
Thrown at lib/routes/castbox/channel.ts:77
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';
if (ep.video === 1 || ep.url?.includes('.mp4')) {
enclosure_type = 'video/mp4';
} else if (ep.url?.includes('.m4a')) {
enclosure_type = 'audio/mp4';
}
return {
title: ep.title,
description: ep.description,
pubDate: parseDate(ep.release_date),
link: `https://castbox.fm/episode/${encodeURIComponent(ep.title)}-id${cid}-id${ep.eid}`,
enclosure_url: ep.url,View on GitHub (pinned to bed535e087)
Solutions
- Confirm the channel actually has episodes on castbox.fm.
- Retry once to rule out transient API hiccup.
- If all channels fail, the `getNonce` params (`{ cid, limit, r: 1, raw: 1, web: 1 }`) likely no longer match Castbox's expected signature — update them.
- Dump the raw episode_list response body to see whether Castbox returns an error code/message.
Defensive patterns
Strategy: try-catch
Type guard
function hasEpisodeList(r: unknown): r is { data: { episode_list: unknown[] } } {
return Boolean(r && typeof r === 'object' && (r as any).data?.episode_list);
} Try / catch
try {
const epData = await ofetch(episodeUrl);
if (!epData?.data?.episode_list) {
// retry once, then throw with the upstream body for diagnosis
}
} catch (e) {
throw new Error(`Castbox episode API unreachable: ${(e as Error).message}`);
} Prevention
- Confirm the channel actually has episodes on the live site before assuming an API bug.
- Keep the `getNonce` parameter set in sync with Castbox's current web client.
- Differentiate 'channel has no episodes' from 'API broke' — consider returning an empty feed for the former.
When it happens
Trigger: Channel exists but has zero episodes and Castbox omits the `episode_list` key entirely; API version bump removes `episode_list`; nonce rejection on the second call; `limit` query param out of accepted range causes Castbox to return an error envelope.
Common situations: Newly created channels with no published episodes, channels that are video-only on a different endpoint, or a breaking change in Castbox's `/episode_list/v2` response schema.
Related errors
- Failed to fetch channel data 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/1485fe49c588a0ff.
Report an issue: GitHub.