{"record":{"id":"821c2dc6d5484545","repo":"jackwener/OpenCLI","slug":"twitter-trending","errorCode":null,"errorMessage":"twitter trending","messagePattern":"twitter trending","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"error","filePath":"clis/twitter/trending.js","lineNumber":54,"sourceCode":"      const items = [];\n      const cells = document.querySelectorAll('[data-testid=\"trend\"]');\n      cells.forEach((cell) => {\n        const text = cell.textContent || '';\n        if (text.includes('Promoted')) return;\n        const container = cell.querySelector(':scope > div');\n        if (!container) return;\n        const divs = container.children;\n        if (divs.length < 2) return;\n        const topic = divs[1].textContent.trim();\n        if (!topic) return;\n        const catText = divs[0].textContent.trim();\n        const category = catText.replace(/^\\\\d+\\\\s*/, '').replace(/^\\\\xB7\\\\s*/, '').trim();\n        items.push({ rank: items.length + 1, topic, category });\n      });\n      return items;\n    })()`);\n        if (!Array.isArray(trends) || trends.length === 0) {\n            throw new EmptyResultError('twitter trending', 'No trends found. The page structure may have changed.');\n        }\n        return trends.slice(0, limit);\n    },\n});\n","sourceCodeStart":36,"sourceCodeEnd":59,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/trending.js#L36-L59","documentation":"trending.js:54 validates the scrape result: the page.evaluate extracting [data-testid=\"trend\"] cells must return a non-empty array. If the structure changed or nothing rendered, EmptyResultError('twitter trending', 'No trends found. The page structure may have changed.') is thrown so the caller knows the extractor, not the data, is likely at fault.","triggerScenarios":"page.evaluate returns undefined/null/non-array, or the trends array is empty because no elements matching [data-testid=\"trend\"] were found after navigating to https://x.com/explore/tabs/trending and waiting ~5 seconds.","commonSituations":"X redesigned the trending markup (data-testid renamed/removed); page still loading or showing a login wall/interstitial after the fixed waits (page.wait(3) + page.wait(2)); region where trends are unavailable; A/B test variants; slow network so trends render after the wait window.","solutions":["Re-run once — slow rendering can beat the fixed waits; if it succeeds intermittently, increase the wait or use a proper waitForSelector('[data-testid=\"trend\"]')","Inspect the /explore/tabs/trending page and update the selector in trending.js if X changed data-testid=\"trend\" to something else","Confirm the account/region actually shows trends (some regions or settings show the 'Timeline' tab without trend items)","Check you are not hitting a logged-out/login-wall variant of the page despite having a session"],"exampleFix":"// before (fixed waits)\nawait page.wait(3);\n// after (wait for the actual elements)\nawait page.waitForSelector('[data-testid=\"trend\"]', { timeout: 15000 });","handlingStrategy":"fallback","validationCode":"// After evaluate, validate shape before use\nconst trends = await page.evaluate('/* scrape IIFE */');\nif (!Array.isArray(trends) || trends.length === 0) {\n  console.warn('No [data-testid=\"trend\"] nodes found — page structure or load timing issue.');\n}","typeGuard":"function isTrendList(value) {\n  return Array.isArray(value)\n    && value.length > 0\n    && value.every((t) => t && typeof t.topic === 'string');\n}","tryCatchPattern":"import { EmptyResultError } from '@jackwener/opencli/errors';\ntry {\n  const trends = await getTrending();\n} catch (e) {\n  if (e instanceof EmptyResultError) {\n    console.warn('No trends extracted; retrying with longer wait or reporting selector drift.');\n    // fallback: retry once, then surface a warning instead of crashing\n  } else throw e;\n}","preventionTips":["Wait for the selector rather than fixed sleeps: waitForSelector('[data-testid=\"trend\"]')","Snapshot the trending page HTML when extraction fails to detect X markup changes early","Add an alert/monitor that fails loudly when trend count drops to 0 for consecutive runs","Pin your automation to a stable region/account settings where trends render consistently"],"tags":["scraping","empty-result","dom-structure","twitter"],"backgroundTag":"empty-scrape-result","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}