DIYgod/RSSHub · error · Error

HTTP error! status: ${res.status}

Error message

HTTP error! status: ${res.status}

What it means

Unlike other routes, this path uses the native `fetch` (not `got`) to call the Fanbox `post.info` API with credentials included, and throws a generic Error echoing `res.status` on any non-OK response. The status code is the key diagnostic: 401 means the session cookie is missing/invalid, 403/451 is an access restriction, 429 is rate limiting.

Source

Thrown at lib/routes/fanbox/utils.tsx:189

    return ret;
}

export function parseItem(page: Page, item: PostItem) {
    return cache.tryGet(`fanbox-${item.id}-${item.updatedDatetime}`, async () => {
        const postDetail: PostDetailResponse = await page.evaluate(
            async ({ url }) => {
                const res = await fetch(url, {
                    method: 'GET',
                    credentials: 'include',
                    headers: {
                        'Sec-Fetch-Dest': 'empty',
                        'Sec-Fetch-Mode': 'cors',
                        'Sec-Fetch-Site': 'same-site',
                    },
                });

                if (!res.ok) {
                    throw new Error(`HTTP error! status: ${res.status}`);
                }

                return res.json();
            },
            { url: `https://api.fanbox.cc/post.info?postId=${item.id}` }
        );

        return {
            title: item.title || 'No title',
            description: await parseDetail(postDetail.body.post),
            pubDate: parseDate(item.updatedDatetime),
            link: `https://${item.creatorId}.fanbox.cc/posts/${item.id}`,
            category: item.tags,
        };
    }) as Promise<DataItem>;
}

async function getSoundCloudEmbedUrl(videoId: string) {

View on GitHub (pinned to bed535e087)

Solutions

  1. Set or refresh the FANBOX_SESSION cookie in your RSSHub config and restart.
  2. Read the status from the message: 401 -> auth, 429 -> back off, 5xx -> retry.
  3. For 429/5xx, retry with exponential backoff; for 401, do not retry until credentials are fixed.

Example fix

// before
//   if (!res.ok) {
//       throw new Error(`HTTP error! status: ${res.status}`);
//   }
// after
//   if (!res.ok) {
//       if (res.status === 401) throw new Error('Fanbox session cookie is missing or expired (401)');
//       if (res.status === 429) throw new Error('Fanbox rate limited (429) - retry later');
//       throw new Error(`HTTP error! status: ${res.status}`);
//   }
Defensive patterns

Strategy: retry

Validate before calling

// Validate credentials presence before calling
if (!config.fanbox?.session) {
  throw new Error('FANBOX_SESSION is not configured — expect 401 from post.info');
}

Try / catch

async function fetchFanbox(url: string) {
  for (let attempt = 0; attempt < 3; attempt++) {
    const res = await fetch(url, { credentials: 'include' });
    if (res.ok) return res.json();
    if (res.status === 401 || res.status === 404) throw new Error(`Fanbox ${res.status}`);
    // 429 / 5xx — back off and retry
    await new Promise((r) => setTimeout(r, 2 ** attempt * 500));
  }
  throw new Error('Fanbox request failed after retries');
}

Prevention

When it happens

Trigger: Calling post.info without a valid FANBOX_SESSION cookie (401); hitting Fanbox rate limits (429); requesting a deleted/creator-restricted post (404); a transient 5xx.

Common situations: Self-hosting without configuring the Fanbox session cookie; the cookie expired since last refresh; aggressive polling tripping rate limits.

Related errors


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