DIYgod/RSSHub · error · Error

Empty post data. The request may be filtered by WAF.

Error message

Empty post data. The request may be filtered by WAF.

What it means

Thrown inside the cache callback of the Douyin user feed route when `postData` is falsy after the Playwright page finishes loading. The route intercepts the `/web/aweme/post` XHR response to capture post data; if that XHR never fires (no response was intercepted), `postData` remains undefined. This is typically caused by Douyin's WAF (Web Application Firewall) blocking or challenging the automated browser before the XHR can complete.

Source

Thrown at lib/routes/douyin/user.ts:74

                const request = route.request();
                request.resourceType() === 'document' || request.resourceType() === 'script' || request.resourceType() === 'xhr' ? route.continue() : route.abort();
            });
            page.on('response', async (response) => {
                const request = response.request();
                if (request.url().includes('/web/aweme/post') && !postData) {
                    postData = await response.json();
                }
            });

            logger.http(`Requesting ${pageUrl}`);
            await page.goto(pageUrl, {
                waitUntil: 'networkidle',
            });

            await context.close();

            if (!postData) {
                throw new Error('Empty post data. The request may be filtered by WAF.');
            }

            return postData;
        },
        config.cache.routeExpire,
        false
    )) as PostData;

    if (!pageData.aweme_list?.length) {
        throw new Error('Empty post data. The request may be filtered by WAF.');
    }
    const userInfo = pageData.aweme_list[0].author;
    const userNickName = userInfo.nickname;
    // const userDescription = userInfo.desc;
    const userAvatar = getOriginAvatar(userInfo.avatar_thumb.url_list.at(-1));

    const items = pageData.aweme_list.map((post) => {
        // parse video

View on GitHub (pinned to bed535e087)

Solutions

  1. Retry after waiting — WAF challenges are often temporary.
  2. Ensure Playwright stealth measures are in place (the RSSHub playwright utils handle some of this).
  3. Run from a residential IP or proxy if datacenter IPs are blocked.
  4. Verify the uid is valid and the user profile is accessible.
Defensive patterns

Strategy: retry

Type guard

interface DouyinPostData {
    aweme_list?: unknown[];
}

function hasPostData(data: unknown): data is DouyinPostData {
    return typeof data === 'object' && data !== null && typeof (data as any).aweme_list !== 'undefined';
}

Try / catch

try {
    const feed = await fetch(`${rsshubUrl}/douyin/user/${uid}`);
} catch (e) {
    if (e.message.includes('filtered by WAF')) {
        // WAF blocks are often temporary — retry after cache expiry
        console.error('Douyin WAF blocked the request. Retry later or use a residential IP.');
    }
    throw e;
}

Prevention

When it happens

Trigger: Douyin's WAF detects Playwright/Puppeteer automation and blocks the page load or the XHR request; network timing issues where the XHR fires after `networkidle` is reached; the user account has been deleted or is geo-restricted; Playwright's request interception aborts the critical XHR.

Common situations: Running from a datacenter IP that Douyin blocks; Playwright detection via navigator.webdriver or other fingerprinting; the user profile doesn't exist or is region-locked; high-frequency requests trigger WAF escalation.

Related errors


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