DIYgod/RSSHub · error · Error

Failed to get series data

Error message

Failed to get series data

What it means

Thrown by the SFW (unauthenticated) novel series path when pixiv's /ajax/novel/series/{seriesId}/content_titles endpoint returns a body with data.error truthy. It re-throws pixiv's own data.message, falling back to 'Failed to get series data' when pixiv omits a message. This is a plain Error (not ConfigNotFoundError or InvalidParameterError), so upstream callers treat it as a generic failure.

Source

Thrown at lib/routes/pixiv/novel-api/series/sfw.ts:28

export async function getSFWSeriesNovels(seriesId: string, limit: number = 10): Promise<SeriesFeed> {
    const seriesPage = await got(`${baseUrl}/novel/series/${seriesId}`);
    const $ = load(seriesPage.data);

    const title = $('meta[property="og:title"]').attr('content') || '';
    const description = $('meta[property="og:description"]').attr('content') || '';
    const image = $('meta[property="og:image"]').attr('content') || '';

    const response = await got(`${baseUrl}/ajax/novel/series/${seriesId}/content_titles`, {
        headers: {
            referer: `${baseUrl}/novel/series/${seriesId}`,
        },
    });

    const data = response.data as SeriesContentResponse;

    if (data.error) {
        throw new Error(data.message || 'Failed to get series data');
    }

    const chapters = data.body.slice(-Math.abs(limit));
    const chapterStartNum = Math.max(data.body.length - limit + 1, 1);

    const items = await Promise.all(
        chapters
            .map(async (chapter, index) => {
                if (!chapter.available) {
                    return {
                        title: `#${chapterStartNum + index} ${chapter.title}`,
                        description: 'PIXIV_REFRESHTOKEN is required to view the full content.<br>需要 PIXIV_REFRESHTOKEN 才能查看完整內文。',
                        link: `${baseUrl}/novel/show.php?id=${chapter.id}`,
                    };
                }

                const novelContent = await getSFWNovelContent(chapter.id);
                return {

View on GitHub (pinned to bed535e087)

Solutions

  1. Open https://www.pixiv.net/novel/series/{seriesId} in a browser to confirm the series still exists and is public.
  2. If the series is R18, switch to the NSFW series route with a configured PIXIV_REFRESHTOKEN.
  3. Verify the seriesId is numeric and matches the URL path segment, not the work ID.
  4. Retry once to rule out a transient pixiv AJAX error.
Defensive patterns

Strategy: try-catch

Validate before calling

function isValidSeriesId(id: string): boolean {
  return /^\d+$/.test(id);
}
// before calling the SFW series fetch:
if (!isValidSeriesId(seriesId)) {
  // reject early with an invalid-parameter style message
}

Type guard

const isSeriesErrorResponse = (d: unknown): d is { error: true; message?: string } =>
  typeof d === 'object' && d !== null && (d as any).error === true;

Try / catch

try {
  return await getSFWSeriesNovels(seriesId, limit);
} catch (e) {
  // plain Error from pixiv AJAX; distinguish from ConfigNotFoundError before surfacing
  if (!(e instanceof Error) || e.name !== 'Error') throw e;
  // series missing/private/age-gated: report to user, optionally try NSFW path
}

Prevention

When it happens

Trigger: seriesId does not exist, was deleted by the author, or is private/age-gated; pixiv AJAX returned HTTP 200 with an error JSON payload; transient pixiv server-side error surfacing through the error field.

Common situations: Series ID typo copied from the wrong URL; series removed since the feed was last fetched; an R18-only series requested through the SFW path that cannot list its chapters without login.

Related errors


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