{"record":{"id":"92cd87ecda96b8a2","repo":"jackwener/OpenCLI","slug":"no-douyin-videos-matched-keyword","errorCode":null,"errorMessage":"No Douyin videos matched \"${keyword}\".","messagePattern":"No Douyin videos matched \"(.+?)\"\\.","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/douyin/search.js","lineNumber":288,"sourceCode":"        }\n        await page.goto(`https://www.douyin.com/search/${encodeURIComponent(keyword)}?type=video`);\n        let result;\n        try {\n            result = unwrapEvaluateResult(await page.evaluate(WAIT_AND_EXTRACT_JS(RENDER_TIMEOUT_MS)));\n        } catch (error) {\n            throw new CommandExecutionError(`Douyin search extraction failed: ${error instanceof Error ? error.message : String(error)}`);\n        }\n        if (!result || typeof result !== 'object') {\n            throw new CommandExecutionError('Douyin search: unexpected evaluator payload shape');\n        }\n        if (result.state === 'login_wall') {\n            throw new AuthRequiredError(\n                'www.douyin.com',\n                'Douyin search results are blocked behind a login wall — log in at https://www.douyin.com in Chrome first.',\n            );\n        }\n        if (result.state === 'empty') {\n            throw new EmptyResultError('douyin search', `No Douyin videos matched \"${keyword}\".`);\n        }\n        if (result.state === 'timeout') {\n            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.');\n        }\n        if (!Array.isArray(result.cards)) {\n            throw new CommandExecutionError('Douyin search: evaluator returned malformed cards payload');\n        }\n        if (result.cards.length === 0) {\n            throw new EmptyResultError('douyin search', `No Douyin videos matched \"${keyword}\".`);\n        }\n        const projected = projectSearchCards(result.cards, limit);\n        if (projected.invalidCount > 0) {\n            throw new CommandExecutionError('Douyin search parser found result cards without stable video url or description');\n        }\n        if (projected.rows.length === 0) {\n            throw new EmptyResultError('douyin search', `No Douyin videos matched \"${keyword}\".`);\n        }\n        return projected.rows;","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/douyin/search.js#L270-L306","documentation":"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.","triggerScenarios":"Searching a keyword with zero Douyin matches (very rare/nonsense query, keyword with only banned/removed videos, or overly specific `--limit` filtering downstream).","commonSituations":"Typo in the keyword; searching niche Chinese-only terms from a wrongly-encoded query; keyword recently scrubbed by moderation; testing against an empty index.","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)."],"exampleFix":"// before\nconst rows = await run(['douyin', 'search', keyword]);\nconsole.log(rows.map(r => r.url));\n// after\ntry {\n  const rows = await run(['douyin', 'search', keyword]);\n  console.log(rows.map(r => r.url));\n} catch (e) {\n  if (e.name === 'EmptyResultError') { console.log([]); return; }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  rows = await douyinSearch(keyword);\n} catch (e) {\n  if (e.name === 'EmptyResultError') return []; // genuinely no matches\n  throw e;\n}","preventionTips":["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."],"tags":["empty-results","douyin","search"],"backgroundTag":"empty-result-set","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}