{"record":{"id":"8c2ec9cab3463fac","repo":"jackwener/OpenCLI","slug":"not-logged-into-x-com-no-ct0-cookie-8c2ec9","errorCode":null,"errorMessage":"Not logged into x.com (no ct0 cookie)","messagePattern":"Not logged into x\\.com \\(no ct0 cookie\\)","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/twitter/trending.js","lineNumber":33,"sourceCode":"    access: 'read',\n    description: 'Twitter/X trending topics',\n    domain: 'x.com',\n    strategy: Strategy.COOKIE,\n    browser: true,\n    args: [\n        { name: 'limit', type: 'int', default: 20, help: 'Number of trends to show' },\n    ],\n    columns: ['rank', 'topic', 'category'],\n    func: async (page, kwargs) => {\n        const limit = kwargs.limit || 20;\n        // Navigate to trending page\n        await page.goto('https://x.com/explore/tabs/trending');\n        await page.wait(3);\n        // Verify login via CSRF cookie (read directly from cookie store via CDP)\n        const cookies = await page.getCookies({ url: 'https://x.com' });\n        const ct0 = cookies.find((c) => c.name === 'ct0')?.value || null;\n        if (!ct0)\n            throw new AuthRequiredError('x.com', 'Not logged into x.com (no ct0 cookie)');\n        await page.wait(2);\n        const trends = await page.evaluate(`(() => {\n      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;","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/trending.js#L15-L51","documentation":"trending.js:33 verifies the x.com session before scraping the trending page by looking for the ct0 CSRF cookie in the cookie store for https://x.com. Its absence means the user is not logged in, so AuthRequiredError('x.com', 'Not logged into x.com (no ct0 cookie)') is thrown — trending content on x.com generally requires a session.","triggerScenarios":"Running `opencli twitter trending` when the driven browser profile is logged out of x.com: no session at all, expired session, cleared cookies, or the pre-nav to https://x.com/explore/tabs/trending redirected to the login page.","commonSituations":"Fresh environment with no logged-in profile; x.com forced a re-login; cookie injection targeting twitter.com instead of x.com; corporate proxy or region redirect breaking the login; automation-detected session termination.","solutions":["Log into x.com in the browser profile the CLI controls, then rerun `opencli twitter trending`","Verify the ct0 cookie exists for https://x.com in the profile (DevTools > Application > Cookies)","If injecting cookies, add both auth_token and ct0 scoped to domain .x.com before navigation","Re-run after x.com-initiated logouts — the cookie check will keep failing until a fresh login establishes ct0"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const cookies = await page.getCookies({ url: 'https://x.com' });\nconst ct0 = cookies.find((c) => c.name === 'ct0')?.value || null;\nif (!ct0) throw new Error('Not logged into x.com: authenticate the CLI browser profile before trending fetch');","typeGuard":"const isLoggedInToX = (cookies) =>\n  Array.isArray(cookies) && cookies.some((c) => c.name === 'ct0' && Boolean(c.value));","tryCatchPattern":"import { AuthRequiredError } from '@jackwener/opencli/errors';\ntry {\n  const trends = await getTrending({ limit: 20 });\n} catch (e) {\n  if (e instanceof AuthRequiredError) {\n    console.error('Login to x.com in the CLI browser profile, then rerun.');\n  } else throw e;\n}","preventionTips":["Verify ct0 exists before navigating to /explore/tabs/trending","Use a persistent profile so sessions survive between runs","Re-login after x.com security-driven session revocations","Detect login-page redirects after navigation as an early signal"],"tags":["authentication","cookies","csrf","twitter"],"backgroundTag":"missing-auth-cookie","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}