DIYgod/RSSHub · error · Error

Blog Not Found

Error message

Blog Not Found

What it means

Thrown by the Lofter user handler (lib/routes/lofter/user.ts:53) when `response.data.response` is falsy OR `response.data.response.posts.length === 0`. The blog either does not exist, has no posts, or the Lofter iPhone API returned an error envelope.

Source

Thrown at lib/routes/lofter/user.ts:53

    const response = await got({
        method: 'post',
        url: 'http://api.lofter.com/v2.0/blogHomePage.api?product=lofter-iphone-10.0.0',
        body: new URLSearchParams({
            blogdomain: rootUrl,
            checkpwd: '1',
            following: '0',
            limit: String(limit),
            method: 'getPostLists',
            needgetpoststat: '1',
            offset: '0',
            postdigestnew: '1',
            supportposttypes: '1,2,3,4,5,6',
        }),
    });

    if (!response.data.response || response.data.response.posts.length === 0) {
        throw new Error('Blog Not Found');
    }

    const items = response.data.response.posts.map((item) => ({
        title: item.post.title || item.post.noticeLinkTitle,
        link: item.post.blogPageUrl,
        description:
            JSON.parse(item.post.photoLinks || '[]')
                .map((photo) => {
                    if (photo.raw?.match(/\/\/nos\.netease\.com\//)) {
                        photo.raw = `https://${photo.raw.match(/(imglf\d)/)[0]}.lf127.net${photo.raw.match(/\/\/nos\.netease\.com\/imglf\d(.*)/)[1]}`;
                    }
                    return `<img src="${photo.raw || photo.orign}">`;
                })
                .join('') +
            JSON.parse(item.post.embed ? `[${item.post.embed}]` : '[]')
                .map((video) => `<video src="${video.originUrl}" poster="${video.video_img_url}" controls="controls"></video>`)
                .join('') +
            item.post.content,

View on GitHub (pinned to bed535e087)

Solutions

  1. Open `https://<name>.lofter.com/` to confirm the blog exists and has posts.
  2. Inspect `response.data` to see whether an error code/message is present under another key.
  3. If the envelope changed, update the guard and the `response.data.response.posts` access path.

Example fix

// before
if (!response.data.response || response.data.response.posts.length === 0) {
    throw new Error('Blog Not Found');
}

// after: distinguish missing blog from empty blog
if (!response.data.response) {
    throw new Error(`Blog Not Found: ${JSON.stringify(response.data.meta || response.data).slice(0, 200)}`);
}
if (response.data.response.posts.length === 0) {
    throw new Error('Blog has no posts');
}
Defensive patterns

Strategy: validation

Validate before calling

function blogHasPosts(data: { response?: { posts?: unknown[] } }): boolean {
    return Boolean(data?.response?.posts && data.response.posts.length > 0);
}

Type guard

interface LofterUserResponse { response: { posts: unknown[] } }
function isLofterUserResponse(d: unknown): d is LofterUserResponse {
    return typeof d === 'object' && d !== null && Array.isArray((d as any)?.response?.posts);
}

Try / catch

try {
    return await fetchLofterUser(name);
} catch (e) {
    if (e instanceof Error && /Blog Not Found/.test(e.message)) {
        return { notFound: true, name };
    }
    throw e;
}

Prevention

When it happens

Trigger: Requesting `/lofter/user/<name>/...` for a non-existent or empty blog; the blog is private/banned; the API envelope changed so `posts` moved; the `supportposttypes` filter excludes all of the blog's posts.

Common situations: Stale username; blog migrated or deleted; API version mismatch after a Lofter update.

Related errors


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