{"record":{"id":"ec2bc6dc14170481","repo":"jackwener/OpenCLI","slug":"x-com-ec2bc6","errorCode":null,"errorMessage":"x.com","messagePattern":"x\\.com","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/twitter/profile.js","lineNumber":101,"sourceCode":"    columns: ['screen_name', 'name', 'bio', 'location', 'url', 'followers', 'following', 'tweets', 'likes', 'verified', 'created_at'],\n    func: async (page, kwargs) => {\n        const rawUsername = String(kwargs.username ?? '').trim();\n        let username = normalizeTwitterScreenName(rawUsername);\n        if (rawUsername && !username) {\n            throw new ArgumentError('twitter profile username must be a valid Twitter/X handle', 'Example: opencli twitter profile @jack');\n        }\n        // If no username, detect the logged-in user.\n        // Bridge wraps primitive page.evaluate returns as { session, data:<value> };\n        // unwrap so the href string is usable downstream.\n        if (!username) {\n            await page.goto('https://x.com/home');\n            await page.wait({ selector: '[data-testid=\"primaryColumn\"]' });\n            const href = unwrapBrowserResult(await page.evaluate(`() => {\n        const link = document.querySelector('a[data-testid=\"AppTabBar_Profile_Link\"]');\n        return link ? link.getAttribute('href') : null;\n      }`));\n            if (!href || typeof href !== 'string')\n                throw new AuthRequiredError('x.com', 'Could not detect logged-in user. Are you logged in?');\n            username = normalizeTwitterScreenName(href);\n            if (!username)\n                throw new AuthRequiredError('x.com', 'Could not detect logged-in user. Are you logged in?');\n        }\n        // Navigate directly to the user's profile page (gives us cookie context)\n        await page.goto(`https://x.com/${username}`);\n        await page.wait(3);\n        // Read CSRF token directly from the cookie store via CDP — zero page.evaluate round-trip\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        const resolvedOperation = await resolveTwitterOperationMetadata(page, 'UserByScreenName', USER_BY_SCREEN_NAME_OPERATION);\n        const operation = { queryId: resolvedOperation.queryId, features: resolvedOperation.features };\n        const rawResult = unwrapBrowserResult(await page.evaluate(`\n      async () => {\n        const screenName = ${JSON.stringify(username)};\n        const ct0 = ${JSON.stringify(ct0)};","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/profile.js#L83-L119","documentation":"AuthRequiredError thrown when no username was given and the command tries to auto-detect the logged-in user by reading the AppTabBar_Profile_Link href from x.com/home, but the link is missing or yields no handle — meaning the session is not logged in (or the home page didn't render the nav).","triggerScenarios":"Calling `opencli twitter profile` without a username while the browser session's x.com/home lacks a[data-testid=\"AppTabBar_Profile_Link\"] (logged out, login wall, or X renamed the nav link), or the href doesn't normalize to a handle.","commonSituations":"Session cookies expired; `opencli login` never run or browser profile reset; X changed the AppTabBar testid after a frontend deploy; x.com/home redirected to the logged-out landing page.","solutions":["Log in: run `opencli login` and complete authentication in the browser","Retry the command after confirming x.com shows the logged-in home timeline","Pass the username explicitly (`opencli twitter profile @handle`) to skip auto-detection entirely","If logged in but the error persists, X likely changed the AppTabBar_Profile_Link selector; report/update it"],"exampleFix":"// before\nopencli twitter profile            # relies on logged-in detection\n// after\nopencli twitter profile @myhandle  # explicit, no auth detection needed","handlingStrategy":"try-catch","validationCode":"// pre-flight: confirm the session is logged in before profile auto-detection\nawait page.goto('https://x.com/home');\nconst loggedIn = await page.evaluate(\n  \"() => !!document.querySelector('a[data-testid=\\\"AppTabBar_Profile_Link\\\"]')\"\n);\nif (!loggedIn) throw new Error('run `opencli login` first');","typeGuard":null,"tryCatchPattern":"try {\n  profile = await opencli('twitter profile'); // auto-detect\n} catch (e) {\n  if (e.name === 'AuthRequiredError') {\n    await opencli('login');\n    profile = await opencli('twitter profile');\n  } else throw e;\n}","preventionTips":["Run `opencli login` before unattended runs","Pass the username explicitly to skip logged-in detection","Periodically re-authenticate; X sessions expire","After X frontend deploys, verify the AppTabBar_Profile_Link selector still exists"],"tags":["auth","twitter","session"],"backgroundTag":"auth-required","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}