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
- Verify the keyword spelling/encoding and retry with a broader term.
- Open the same search in a browser to confirm Douyin really shows no results.
- 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
- Sanity-check keywords (spelling, encoding) before querying.
- Spot-check the same search in a browser when a result set of zero is surprising.
- Treat empty results as data, not failure, in pipelines.
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
- No items match "${query}" on archive.org.
- No hotels rendered (${totalText}). Try a broader destination
- douyin search
- douyin stats ${awemeId}
- flathub search
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/92cd87ecda96b8a2.
Report an issue: GitHub.