jackwener/OpenCLI · warning · EmptyResultError

No Douyin videos matched "${keyword}".

Error message

No Douyin videos matched "${keyword}".

What it means

EmptyResultError thrown when the Douyin search evaluator reports state === 'empty' — the page rendered successfully and the user is authenticated, but no result cards exist for the keyword. The CLI surfaces this distinctly from timeouts and login walls so callers know the search genuinely matched nothing.

Source

Thrown at clis/douyin/search.js:288

        }
        await page.goto(`https://www.douyin.com/search/${encodeURIComponent(keyword)}?type=video`);
        let result;
        try {
            result = unwrapEvaluateResult(await page.evaluate(WAIT_AND_EXTRACT_JS(RENDER_TIMEOUT_MS)));
        } catch (error) {
            throw new CommandExecutionError(`Douyin search extraction failed: ${error instanceof Error ? error.message : String(error)}`);
        }
        if (!result || typeof result !== 'object') {
            throw new CommandExecutionError('Douyin search: unexpected evaluator payload shape');
        }
        if (result.state === 'login_wall') {
            throw new AuthRequiredError(
                'www.douyin.com',
                'Douyin search results are blocked behind a login wall — log in at https://www.douyin.com in Chrome first.',
            );
        }
        if (result.state === 'empty') {
            throw new EmptyResultError('douyin search', `No Douyin videos matched "${keyword}".`);
        }
        if (result.state === 'timeout') {
            throw new CommandExecutionError('Douyin search did not render result cards within the timeout. Open the same search in Chrome and verify login/security state before retrying.');
        }
        if (!Array.isArray(result.cards)) {
            throw new CommandExecutionError('Douyin search: evaluator returned malformed cards payload');
        }
        if (result.cards.length === 0) {
            throw new EmptyResultError('douyin search', `No Douyin videos matched "${keyword}".`);
        }
        const projected = projectSearchCards(result.cards, limit);
        if (projected.invalidCount > 0) {
            throw new CommandExecutionError('Douyin search parser found result cards without stable video url or description');
        }
        if (projected.rows.length === 0) {
            throw new EmptyResultError('douyin search', `No Douyin videos matched "${keyword}".`);
        }
        return projected.rows;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify the keyword spelling/encoding and retry with a broader term.
  2. Open the same search in a browser to confirm Douyin really shows no results.
  3. Handle EmptyResultError in the caller as an expected, non-fatal outcome (empty rows).

Example fix

// before
const rows = await run(['douyin', 'search', keyword]);
console.log(rows.map(r => r.url));
// after
try {
  const rows = await run(['douyin', 'search', keyword]);
  console.log(rows.map(r => r.url));
} catch (e) {
  if (e.name === 'EmptyResultError') { console.log([]); return; }
  throw e;
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  rows = await douyinSearch(keyword);
} catch (e) {
  if (e.name === 'EmptyResultError') return []; // genuinely no matches
  throw e;
}

Prevention

When it happens

Trigger: Searching a keyword with zero Douyin matches (very rare/nonsense query, keyword with only banned/removed videos, or overly specific `--limit` filtering downstream).

Common situations: Typo in the keyword; searching niche Chinese-only terms from a wrongly-encoded query; keyword recently scrubbed by moderation; testing against an empty index.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/92cd87ecda96b8a2. Report an issue: GitHub.