{"record":{"id":"65c29249cf11e67f","repo":"jackwener/OpenCLI","slug":"could-not-find-logged-in-user-profile-link-are-yo","errorCode":null,"errorMessage":"Could not find logged-in user profile link. Are you logged in?","messagePattern":"Could not find logged-in user profile link\\. Are you logged in\\?","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/twitter/followers.js","lineNumber":120,"sourceCode":"            throw new ArgumentError('twitter followers user must be a valid Twitter/X handle', 'Example: opencli twitter followers @elonmusk --limit 100');\n        }\n        await page.goto('https://x.com/home');\n        await page.wait({ selector: '[data-testid=\"primaryColumn\"]' });\n        const cookies = await page.getCookies({ url: 'https://x.com' });\n        const ct0 = cookies.find((cookie) => cookie.name === 'ct0')?.value || null;\n        if (!ct0) {\n            throw new AuthRequiredError('x.com', 'Not logged into x.com (no ct0 cookie)');\n        }\n\n        if (!targetUser) {\n            // Bridge wraps primitive page.evaluate returns as { session, data:<value> };\n            // unwrap so the href string is usable downstream.\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 find logged-in user profile link. Are you logged in?');\n            }\n            targetUser = normalizeScreenName(href);\n            if (!targetUser) {\n                throw new AuthRequiredError('x.com', 'Could not find logged-in user profile link. Are you logged in?');\n            }\n        }\n        if (!targetUser) {\n            throw new ArgumentError('twitter followers user cannot be empty', 'Example: opencli twitter followers @elonmusk --limit 100');\n        }\n\n        await page.installInterceptor('/Followers?');\n        const targetPath = `/${targetUser}/followers`;\n        await page.evaluate(`() => {\n            const targetPath = ${JSON.stringify(targetPath)};\n            window.history.pushState({}, '', targetPath);\n            window.dispatchEvent(new PopStateEvent('popstate', { state: {} }));\n        }`);\n        try {","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/followers.js#L102-L138","documentation":"When no user argument is supplied the command resolves the logged-in account by reading the href of the AppTabBar_Profile_Link element on x.com/home. If the selector returns null or a non-string (e.g. X renamed the testid, or the DOM differs), it cannot determine whose followers to fetch and throws AuthRequiredError. The second message variant means the page is likely not a logged-in home view.","triggerScenarios":"Running without a user argument while the profile link a[data-testid=\"AppTabBar_Profile_Link\"] is missing from the rendered home page — logged-out state, X A/B test changing the testid, page not fully hydrated, or a localized/variant DOM.","commonSituations":"X front-end update renaming the data-testid; scraping before hydration completes; semi-logged-in state where ct0 exists but home renders logged-out chrome; running against an unsupported locale/layout experiment.","solutions":["Log into x.com in the tool's browser profile and confirm the profile avatar appears on home","Pass the target handle explicitly (opencli twitter followers @handle) to bypass profile-link detection","Update shared.js/library if X changed the data-testid, and re-run","Retry after the page fully loads; transient hydration timing can hide the link"],"exampleFix":"// before (relies on logged-in home)\nopencli twitter followers\n// after (explicit target)\nopencli twitter followers @elonmusk --limit 100","handlingStrategy":"try-catch","validationCode":"const href = await page.evaluate(`() => document.querySelector('a[data-testid=\"AppTabBar_Profile_Link\"]')?.getAttribute('href') ?? null`);\nif (!href) throw new Error('Pass an explicit user: opencli twitter followers @handle');","typeGuard":"null","tryCatchPattern":"try {\n  const rows = await opencli.twitter.followers();\n} catch (err) {\n  if (err instanceof AuthRequiredError && err.message.includes('profile link')) {\n    const rows = await opencli.twitter.followers(myKnownHandle); // explicit-user fallback\n  } else throw err;\n}","preventionTips":["Pass the target handle explicitly to skip profile-link detection","Confirm you see your avatar on x.com/home before running userless invocations","Keep the library updated for X data-testid changes","Retry once after the page fully hydrates"],"tags":["auth","twitter","dom-selector","scraping"],"backgroundTag":"dom-selector-missing","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}