DIYgod/RSSHub · error · Error

Failed to parse blogList from RSC data

Error message

Failed to parse blogList from RSC data

What it means

Thrown when the Manus blog handler cannot extract a blogList object from the React Server Components (RSC) payload returned by https://manus.im/blog with header RSC:1. The parser scans line-by-line for the marker substring '{"blogList":{"$typeName"', slices to the last brace, JSON.parses, and gives up if no usable blogList.groups is found.

Source

Thrown at lib/routes/manus/blog.ts:69

    const lines = renderData.split('\n');
    for (const line of lines) {
        if (!line.includes('{"blogList":{"$typeName"')) {
            continue;
        }

        const jsonStr = line.slice(Math.max(0, line.indexOf('{"blogList":{"$typeName"')));
        const lastBrace = jsonStr.lastIndexOf('}');
        try {
            const parsed = JSON.parse(jsonStr.slice(0, Math.max(0, lastBrace + 1)));
            blogList = parsed.blogList;
            break;
        } catch {
            // Ignore parse errors and try next line if any
        }
    }

    if (!blogList || !blogList.groups) {
        throw new Error('Failed to parse blogList from RSC data');
    }

    const list: Array<DataItem & { _contentUrl?: string }> = blogList.groups.flatMap(
        (group) =>
            group.blogs?.map((blog) => ({
                title: blog.title,
                link: `https://manus.im/blog/${blog.recordUid}`,
                pubDate: new Date(blog.createdAt.seconds * 1000),
                description: blog.desc,
                category: [group.kindName],
                _contentUrl: blog.contentUrl,
            })) ?? []
    );

    const items: DataItem[] = await Promise.all(
        list.map(
            (item) =>
                cache.tryGet(String(item.link), async () => {

View on GitHub (pinned to bed535e087)

Solutions

  1. Reproduce the request: curl -H 'RSC: 1' https://manus.im/blog and grep for blogList to confirm the marker still exists.
  2. If Manus renamed the key, update the marker substring in blog.ts (lines 53 and 57) to the new shape.
  3. If Cloudflare blocked the request, route through a different IP / set a trueUA / use config.trueUA.
  4. Log renderData length and the matched line count to diagnose silent failures.

Example fix

// before
if (!blogList || !blogList.groups) {
    throw new Error('Failed to parse blogList from RSC data');
}
// after
if (!blogList || !blogList.groups) {
    const hint = renderData.length < 200 ? 'response too short (possibly a challenge page)' : 'blogList marker not found';
    throw new Error(`Failed to parse blogList from RSC data: ${hint}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

const MARKER = '{"blogList":{"$typeName"';
if (!renderData.includes(MARKER)) {
    // Manus likely changed the RSC shape or returned a challenge page
    throw new Error('manus.im RSC payload missing blogList marker');
}

Type guard

interface ManusBlogList { groups: Array<{ blogs?: unknown[]; kindName: string }>; }
const isBlogList = (v: unknown): v is ManusBlogList =>
    typeof v === 'object' && v !== null && Array.isArray((v as any).groups);

Try / catch

try {
    blogList = parseBlogList(renderData);
} catch (e) {
    // fall back to a stable 'feed temporarily unavailable' instead of crashing the route
    return { title: 'Manus Blog', item: [] };
}

Prevention

When it happens

Trigger: ofetch returns an RSC payload that no longer contains the '{"blogList":{"$typeName"' marker, the slice/JSON.parse never succeeds for any line, or blogList exists but has no groups field. Caused by Manus changing their RSC payload shape, returning a non-RSC error page (Cloudflare challenge, 403, maintenance), or an empty blog.

Common situations: Manus shipped a frontend change renaming/restructuring blogList; CDN/Cloudflare blocked the RSSHub IP and returned an HTML challenge instead of RSC; transient empty state; the lastBrace slicing logic mis-truncating when the JSON spans differently.

Understand the failure class

Related errors


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