{"record":{"id":"4fa590c30022c6f8","repo":"DIYgod/RSSHub","slug":"response-message-error-code-response-code-4fa590","errorCode":null,"errorMessage":"response.message ?? `Error code ${response.code}`","messagePattern":"response\\.message \\?\\? `Error code (.+?)`","errorType":"exception","errorClass":null,"httpStatus":503,"severity":"error","filePath":"lib/routes/bilibili/message-like.ts","lineNumber":114,"sourceCode":"    const cookie = config.bilibili.cookies[uid];\n    if (cookie === undefined) {\n        throw new ConfigNotFoundError('缺少对应 uid 的 Bilibili 用户登录后的 Cookie 值');\n    }\n\n    const response = await ofetch<LikeResponse>('https://api.bilibili.com/x/msgfeed/like', {\n        query: {\n            platform: 'web',\n            build: 0,\n            mobi_app: 'web',\n        },\n        headers: {\n            Referer: 'https://message.bilibili.com/',\n            Cookie: cookie,\n        },\n    });\n\n    if (response.code !== 0) {\n        throw new Error(response.message ?? `Error code ${response.code}`);\n    }\n\n    const allItems = [...(response.data.latest?.items || []), ...(response.data.total?.items || [])];\n\n    // Deduplicate by id\n    const uniqueItems = allItems.filter((item, index, self) => index === self.findIndex((t) => t.id === item.id));\n\n    const items: DataItem[] = uniqueItems.map((item) => {\n        const likeUsers = item.users;\n        const likeItem = item.item;\n        const counts = item.counts;\n\n        const userNames = likeUsers.map((u) => u.nickname).join('、');\n        const displayNames = counts > likeUsers.length ? `${userNames} 等 ${counts} 人` : userNames;\n\n        let description = `<p><strong>${displayNames}</strong> 赞了你的${likeItem.business}：</p>`;\n        description += `<p><strong>${likeItem.title}</strong></p>`;\n","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/bilibili/message-like.ts#L96-L132","documentation":"Thrown by the bilibili message-like route after the authenticated request to https://api.bilibili.com/x/msgfeed/like succeeds at the HTTP layer but returns a non-zero business `code`. Bilibili APIs always answer 200 OK with a JSON body whose `code` field signals success (0) or failure (negative); when code !== 0 the route raises a plain Error carrying the upstream `message` (or a fallback 'Error code N'). It means the cookie was present and accepted by the network, but Bilibili rejected the call at the application layer.","triggerScenarios":"GET /bilibili/message/like/:uid where the configured BILIBILI_COOKIE_{uid} is expired, revoked, or belongs to a restricted account, so msgfeed/like returns code -101 (账号未登录) or -352 (风控校验). Also triggered when the uid in the path does not match the account the cookie belongs to.","commonSituations":"SESSDATA expired (Bilibili rotates it on password change / security events); cookie copied without the bili_jct / DedeUserID fields; account hit by anti-crawler risk control from too many RSSHub polls; bilibili changed the msgfeed/like response contract.","solutions":["Refresh the cookie: log in to bilibili.com in a clean browser session, re-copy the full Cookie header (including SESSDATA, bili_jct, DedeUserID), and update BILIBILI_COOKIE_{uid}.","Check the numeric code in the error text: -101 means not-logged-in (cookie invalid), -352/-799 means risk control (slow down or use a different account), -403 means permission denied.","Reduce polling frequency in your RSS reader (e.g. interval >= 10 min) to avoid tripping Bilibili's rate/risk limits.","Verify the cookie's DedeUserID matches the uid in the route path."],"exampleFix":"// before\nconst response = await ofetch<LikeResponse>(URL, { headers: { Cookie: cookie } });\nif (response.code !== 0) {\n    throw new Error(response.message ?? `Error code ${response.code}`);\n}\n\n// after (classify known auth failures for clearer UX)\nif (response.code !== 0) {\n    if (response.code === -101) {\n        throw new ConfigNotFoundError(`Bilibili cookie for uid ${uid} is invalid or expired (code -101)`);\n    }\n    throw new Error(response.message ?? `Error code ${response.code}`);\n}","handlingStrategy":"retry","validationCode":"// Pre-flight: verify the cookie still authenticates before serving the feed.\nimport ofetch from '@/utils/ofetch';\nimport { config } from '@/config';\n\nasync function isBilibiliCookieValid(uid: string): Promise<boolean> {\n  const cookie = config.bilibili.cookies[uid];\n  if (!cookie) return false;\n  try {\n    const nav = await ofetch<{ code: number }>('https://api.bilibili.com/x/web-interface/nav', {\n      headers: { Cookie: cookie },\n    });\n    return nav.code === 0; // -101 means expired/invalid\n  } catch {\n    return false;\n  }\n}","typeGuard":"// Narrow a Bilibili API response into success vs failure.\ninterface BiliEnvelope<T> { code: number; message?: string; data?: T }\n\nfunction isBiliSuccess<T>(r: BiliEnvelope<T>): r is BiliEnvelope<T> & { code: 0; data: T } {\n  return r.code === 0;\n}","tryCatchPattern":"try {\n  const response = await ofetch<LikeResponse>(URL, { headers: { Cookie: cookie } });\n  if (response.code !== 0) throw new Error(response.message ?? `Error code ${response.code}`);\n  // ...\n} catch (e) {\n  const msg = e instanceof Error ? e.message : String(e);\n  if (msg.includes('-101')) {\n    // cookie expired -> surface a config-refresh hint, do NOT retry blindly\n    throw new Error(`BILIBILI_COOKIE_${uid} expired; please refresh it.`);\n  }\n  if (msg.includes('-352') || msg.includes('-799')) {\n    // transient risk control -> safe to retry with backoff\n    await backoffRetry(() => ofetch(URL, opts));\n  }\n  throw e;\n}","preventionTips":["Periodically validate each BILIBILI_COOKIE_* against the /x/web-interface/nav endpoint and alert when it starts returning -101.","Cache the msgfeed/like response for a few minutes (cache.tryGet) to avoid hammering Bilibili on every reader poll.","Keep RSS reader poll intervals >= 10 minutes to stay below Bilibili's risk-control threshold.","Store the cookie's DedeUserID alongside the env var and assert it matches the route uid."],"tags":["bilibili","api-error","authentication","anti-crawler","rsshub"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}