DIYgod/RSSHub · error · Error

Got error code ${data.code} while fetching: ${data.message}

Error message

Got error code ${data.code} while fetching: ${data.message}

What it means

Thrown by the bilibili/video API path (fetchVideoListFromApi) when the wbi-signed GET to https://api.bilibili.com/x/space/wbi/arc/search returns a non-zero business code. The handler logs the full data payload at error level, then re-throws the upstream code and message. This is the primary failure mode for the user-video feed and is what triggers the browser-mode fallback in getVideoList().

Source

Thrown at lib/routes/bilibili/video.ts:168

    const dmImgList = utils.getDmImgList();
    const dmImgInter = utils.getDmImgInter();
    const renderData = await cache.getRenderData(uid);

    const params = utils.addWbiVerifyInfo(
        utils.addRenderData(utils.addDmVerifyInfoWithInter(`mid=${uid}&ps=30&tid=0&pn=1&keyword=&order=pubdate&platform=web&web_location=1550101&order_avoided=true`, dmImgList, dmImgInter), renderData),
        wbiVerifyString
    );
    const response = await got(`https://api.bilibili.com${videoListApiPath}?${params}`, {
        headers: {
            Referer: `https://space.bilibili.com/${uid}`,
            origin: 'https://space.bilibili.com',
            Cookie: cookie,
        },
    });
    const data = response.data;
    if (data.code) {
        logger.error(JSON.stringify(data.data));
        throw new Error(`Got error code ${data.code} while fetching: ${data.message}`);
    }

    return data.data;
}

async function fetchVideoListFromBrowser(uid: string): Promise<VideoListData> {
    const cookie = cache.getConfiguredCookie();
    const videoUrl = `https://space.bilibili.com/${uid}/video`;
    logger.info(`[bilibili/video] fetching via playwright: ${videoUrl}`);

    const { destroy, page } = await getPlaywrightPage(videoUrl, {
        closeTimeout: browserCloseTimeout,
        noGoto: true,
        onBeforeLoad: async (page) => {
            if (cookie) {
                await applyCookie(page, cookie);
            }

View on GitHub (pinned to bed535e087)

Solutions

  1. Set BILIBILI_COOKIE_* so cache.getCookie() returns a valid session and the request is authenticated.
  2. Verify the uid exists (open https://space.bilibili.com/{uid}/video in a browser).
  3. Clear the wbi verify cache key (cache.getWbiVerifyString) so the signature keys refresh; ensure buvid is being fetched.
  4. Decode the code: -101 cookie invalid, -352/-479 risk control (slow down, rotate IP), -400 bad request (check uid).
  5. Note the route already falls back to browser mode on this error — if that also fails you'll see error 119/116/117.

Example fix

// before
if (data.code) {
    logger.error(JSON.stringify(data.data));
    throw new Error(`Got error code ${data.code} while fetching: ${data.message}`);
}

// after (map common codes to actionable hints)
if (data.code) {
    logger.error(`[bilibili/video] api code ${data.code}: ${JSON.stringify(data.data)}`);
    if (data.code === -101) {
        throw new ConfigNotFoundError(`Bilibili cookie missing/invalid for uid ${uid} (code -101)`);
    }
    throw new Error(`Got error code ${data.code} while fetching: ${data.message ?? 'no message'}`);
}
Defensive patterns

Strategy: retry

Validate before calling

// Health-check the wbi-signed video API for a uid before relying on it.
import ofetch from '@/utils/ofetch';
async function videoApiOk(uid: string, signedQuery: string) {
  const r = await ofetch<{ code: number }>(`https://api.bilibili.com/x/space/wbi/arc/search?${signedQuery}`, {
    headers: { Referer: `https://space.bilibili.com/${uid}` },
  });
  return r.code === 0;
}

Type guard

interface VideoListResponse { code?: number; data?: VideoListData; message?: string }
function isVideoListOk(r: VideoListResponse): r is { code: 0; data: VideoListData } {
  return r.code === 0 && !!r.data;
}

Try / catch

try {
  if (data.code) throw new Error(`code ${data.code}: ${data.message}`);
} catch (e) {
  const m = e instanceof Error ? e.message : '';
  if (m.includes('-101')) throw new Error(`Set or refresh BILIBILI_COOKIE_* (session invalid)`);
  if (m.includes('-352') || m.includes('-479') || m.includes('-799')) {
    // risk control — the route already falls back to browser mode; if that also fails, backoff
    await backoffRetry();
  }
  throw e;
}

Prevention

When it happens

Trigger: GET /bilibili/user/video/:uid where the wbi/arc/search API answers code !== 0 — most often -352/-479 (risk control / anti-crawler, frequently because the wbi signature is stale or missing buvid/cookie), -101 (not logged in), or -400 (request invalid, e.g. bad uid).

Common situations: No BILIBILI_COOKIE_* configured and the public wbi signature was rejected; wbi keys (cache.getWbiVerifyString) stale; RSSHub IP flagged; uid invalid or deleted; buvid/dm_img missing in the signed params.

Related errors


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