jackwener/OpenCLI · warning · EmptyResultError

douyin search

Error message

douyin search

What it means

The string 'douyin search' here is the scope/resource argument of an EmptyResultError, not the message: it identifies which command produced the empty outcome. It is thrown when result.cards is an empty array — the page rendered, the user is logged in, but the extractor found zero result rows.

Source

Thrown at clis/douyin/search.js:297

            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. Open the search in the bound browser to see if cards visibly render; if they do, the selector hook changed and needs updating.
  2. Retry with a common keyword to distinguish a real empty result from selector rot.
  3. Treat EmptyResultError with scope 'douyin search' as an expected empty outcome in scripts.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  rows = await douyinSearch(keyword);
} catch (e) {
  if (e.name === 'EmptyResultError' && e.scope === 'douyin search') return [];
  throw e;
}

Prevention

When it happens

Trigger: Evaluator collected no <li> rows inside [data-e2e=scroll-list]: query genuinely has no results, or Douyin changed the container markup so the selector matches nothing while state still reports ok.

Common situations: Douyin DOM churn renaming data-e2e hooks; keyword with zero matches; region-locked results hidden for the session's locale.

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/b8250a2b393a32d0. Report an issue: GitHub.