{"record":{"id":"95c769dc041e3773","repo":"jackwener/OpenCLI","slug":"command-page-loaded-but-no-matching-rows-were-f","errorCode":null,"errorMessage":"${command} page loaded but no matching rows were found","messagePattern":"(.+?) page loaded but no matching rows were found","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/dribbble/utils.js","lineNumber":82,"sourceCode":"    return match[1];\n}\n\nexport function requireRows(payload, command) {\n    if (!payload || typeof payload !== 'object') {\n        throw new CommandExecutionError(`${command} returned an unreadable browser payload`);\n    }\n    if (payload.empty) {\n        throw new EmptyResultError(command, payload.reason || `${command} returned no results`);\n    }\n    if (!payload.ok) {\n        const reason = payload.reason ? `: ${payload.reason}` : '';\n        throw new CommandExecutionError(`${command} selector drift${reason}`);\n    }\n    if (!Array.isArray(payload.rows)) {\n        throw new CommandExecutionError(`${command} returned a malformed rows payload`);\n    }\n    if (payload.rows.length === 0) {\n        throw new EmptyResultError(command, `${command} page loaded but no matching rows were found`);\n    }\n    return payload.rows;\n}\n\nexport function requireRow(payload, command) {\n    if (!payload || typeof payload !== 'object') {\n        throw new CommandExecutionError(`${command} returned an unreadable browser payload`);\n    }\n    if (payload.empty) {\n        throw new EmptyResultError(command, payload.reason || `${command} was not found`);\n    }\n    if (!payload.ok || !payload.row) {\n        const reason = payload.reason ? `: ${payload.reason}` : '';\n        throw new CommandExecutionError(`${command} selector drift${reason}`);\n    }\n    return payload.row;\n}\n","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/dribbble/utils.js#L64-L100","documentation":"requireRows validates the browser-scrape payload returned by a Dribbble page task. After the page loads and the selector is found, an empty rows array means the page rendered correctly but zero matching items were matched, so an EmptyResultError is thrown with this message instead of returning an empty list. The library treats 'page loaded, nothing found' as a distinct typed condition (EMPTY_RESULT) so callers can distinguish it from selector drift or argument errors.","triggerScenarios":"Calling any list-style Dribbble command (via rows -> requireRows) where page.goto succeeds, the rows container selector matches, but payload.rows is [] — e.g. a search/shot list query with no results, filters excluding everything, or Dribbble rendering an empty state behind a wall.","commonSituations":"Searching Dribbble for a rare/nonexistent keyword; combining query + time filters that exclude all shots; scraping a profile with no shots; Dribbble A/B changing markup so rows extract nothing while the container still exists.","solutions":["Broaden the search query or remove filters (limit/time) that may exclude all rows","Verify the target page actually has matching content in a real browser; retry later if it is a rendering/anti-bot issue","Catch EmptyResultError in your wrapper and surface a friendly 'no results' message to the end user","Update selector/extractor code in the CLI if Dribbble's markup changed"],"exampleFix":"// before\nconst rows = await runBrowserTask('dribbble shots', extractShotRows(limit));\n// after\ntry {\n  const rows = await runBrowserTask('dribbble shots', extractShotRows(limit));\n} catch (err) {\n  if (err.code === 'EMPTY_RESULT') return [];\n  throw err;\n}","handlingStrategy":"try-catch","validationCode":"// no pre-call validation possible; result depends on remote content\n// optionally: if (!keyword || keyword.trim().length === 0) throw new Error('keyword required');","typeGuard":"function hasRows(payload) {\n  return payload != null && typeof payload === 'object' && Array.isArray(payload.rows) && payload.rows.length > 0;\n}","tryCatchPattern":"try {\n  const rows = await rowsTask();\n} catch (err) {\n  if (err?.code === 'EMPTY_RESULT') return [];\n  throw err;\n}","preventionTips":["Validate queries/filters before invoking so empty outcomes are intentional","Design the caller to handle EMPTY_RESULT as a normal 'no data' outcome","Add a debug mode to dump the loaded page when zero rows appear","Keep selectors updated against Dribbble markup changes"],"tags":["empty-result","scraping","cli"],"backgroundTag":"empty-result-set","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}