DIYgod/RSSHub · error

response.message ?? `Error code

Error message

response.message ?? `Error code ${response.code}`

What it means

Generic Error thrown by the message-at route when Bilibili's /x/msgfeed/at API returns a non-zero code. The error message is response.message if present, otherwise a formatted 'Error code N' string. This fires after a successful authenticated request but when Bilibili returns an error payload (e.g., rate limiting, session issues, or API changes).

Solutions

  1. Inspect the response.code and response.message to identify the specific Bilibili error.
  2. If -101 or -6, refresh the cookie via browser re-login.
  3. If -509, reduce polling frequency and increase cache expiry.
  4. If the error persists, verify the msgfeed API hasn't changed by testing the endpoint manually.

Example fix

// before
if (response.code !== 0) {
    throw new Error(response.message ?? `Error code ${response.code}`);
}

// after: include actionable context
if (response.code !== 0) {
    const hint = response.code === -101 ? ' (cookie may be expired — refresh BILIBILI_COOKIE)'
        : response.code === -509 ? ' (rate limited — reduce frequency)'
        : '';
    throw new Error(`msgfeed/at error ${response.code}: ${response.message ?? 'unknown'}${hint}`);
}
Defensive patterns

Strategy: try-catch

Type guard

interface BilibiliApiResponse {
    code: number;
    message?: string;
    data?: unknown;
}

function isApiError(response: BilibiliApiResponse): boolean {
    return response.code !== 0;
}

Try / catch

try {
    const response = await ofetch<AtResponse>(url, {...});
    if (response.code !== 0) {
        const hint = response.code === -101 ? ' (refresh cookie)'
            : response.code === -509 ? ' (rate limited)'
            : '';
        throw new Error(`${response.message ?? `code ${response.code}`}${hint}`);
    }
} catch (e) {
    logger.error(`msgfeed/at failed: ${e.message}`);
    throw e;
}

Prevention

When it happens

Trigger: The msgfeed/at endpoint returns response.code !== 0 despite a valid cookie being attached. Possible codes: -101 (not logged in / cookie issues at a sub-service level), -509 (rate limited), -7 (account restricted), or temporary backend errors.

Common situations: Polling the mentions feed too frequently; cookie partially expired (SESSDATA present but DedeUserID mismatch); Bilibili added new requirements to the msgfeed endpoint; account flagged for API automation.

Related errors


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

Appendix: source

Thrown at lib/routes/bilibili/message-at.ts:105

    const cookie = config.bilibili.cookies[uid];
    if (cookie === undefined) {
        throw new ConfigNotFoundError('缺少对应 uid 的 Bilibili 用户登录后的 Cookie 值');
    }

    const response = await ofetch<AtResponse>('https://api.bilibili.com/x/msgfeed/at', {
        query: {
            platform: 'web',
            build: 0,
            mobi_app: 'web',
        },
        headers: {
            Referer: 'https://message.bilibili.com/',
            Cookie: cookie,
        },
    });

    if (response.code !== 0) {
        throw new Error(response.message ?? `Error code ${response.code}`);
    }

    const items: DataItem[] = (response.data.items || []).map((item) => {
        const atUser = item.user;
        const atItem = item.item;
        const sourceContent = atItem.source_content;

        let description = `<p><strong>${atUser.nickname}</strong> @了你:</p>`;
        description += `<blockquote>${sourceContent}</blockquote>`;

        if (atItem.image) {
            description += `<p><img src="${atItem.image.replace('http://', 'https://')}" /></p>`;
        }

        description += `<p>来自:${atItem.business} - ${atItem.title}</p>`;

        // Generate link with root_id for direct navigation
        let link = atItem.uri;

View on GitHub (pinned to bed535e087)