jackwener/OpenCLI · error · AuthRequiredError

Could not detect the logged-in Twitter/X profile link

Error message

Could not detect the logged-in Twitter/X profile link

What it means

After confirming session cookies exist, verifyTwitterIdentity reads the screen name (via readScreenName or readSettledScreenName). If the normalized username comes back empty, the logged-in profile link could not be detected, and it throws AuthRequiredError('x.com', 'Could not detect the logged-in Twitter/X profile link'). Cookies exist but identity is unverifiable, so the CLI treats it as an auth problem.

Source

Thrown at clis/twitter/auth.js:65

    }
  }
  const tail = samples.slice(-SCREEN_NAME_AGREEMENTS);
  const username = tail[0] || '';
  return username && tail.every((sample) => sample === username) ? username : '';
}

async function verifyTwitterIdentity(page, { phase } = {}) {
  if (!await hasTwitterSessionCookies(page)) {
    throw new AuthRequiredError('x.com', 'Twitter/X auth cookies are missing');
  }
  await page.goto('https://x.com/home');
  await page.wait({ selector: '[data-testid="primaryColumn"]' }).catch(() => { });
  // Login polls repeat every ~2s; they keep the single read and skip the #2252 settle loop.
  const username = phase === 'poll'
    ? await readScreenName(page)
    : await readSettledScreenName(page);
  if (!username) {
    throw new AuthRequiredError('x.com', 'Could not detect the logged-in Twitter/X profile link');
  }
  return { username, url: `https://x.com/${username}` };
}

registerSiteAuthCommands({
  site: 'twitter',
  domain: 'x.com',
  loginUrl: 'https://x.com/i/flow/login',
  columns: ['username', 'url'],
  quickCheck: hasTwitterSessionCookies,
  verify: verifyTwitterIdentity,
  poll: async (page, options) => {
    if (!await hasTwitterSessionCookies(page)) {
      throw new AuthRequiredError('x.com', 'Waiting for Twitter/X auth cookies');
    }
    return verifyTwitterIdentity(page, options);
  },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Log out and log back in to x.com so the session is genuinely valid, then retry.
  2. Increase the settle patience by retrying the command; slow page loads can leave the profile link unread.
  3. Verify in the controlled browser that x.com shows the logged-in nav bar with your profile link.
  4. Update the CLI if Twitter changed the data-testid attributes the probe relies on.

Example fix

// before
await page.goto('https://x.com/home');
const { username } = await verifyTwitterIdentity(page);
// after
await page.goto('https://x.com/home');
let identity;
try { identity = await verifyTwitterIdentity(page); }
catch (e) { await loginX(); identity = await verifyTwitterIdentity(page); }
Defensive patterns

Strategy: fallback

Validate before calling

await page.goto('https://x.com/home');
const profileLink = await page.waitForSelector('a[data-testid="AppTabBar_Profile_Link"]', { timeout: 8000 }).catch(() => null);
if (!profileLink) await reloginX();

Try / catch

try {
  identity = await verifyTwitterIdentity(page, { phase: 'verify' });
} catch (e) {
  if (/profile link/.test(e.message)) {
    await reloginX(); // stale session: cookies exist but are invalid server-side
    identity = await verifyTwitterIdentity(page, { phase: 'verify' });
  } else throw e;
}

Prevention

When it happens

Trigger: hasTwitterSessionCookies passes but readScreenName/readSettledScreenName returns '' — profile link missing, href empty, or screen name not stable across settle samples.

Common situations: x.com redirects to the login flow despite stale cookies (session invalid server-side), the home page fails to render the primary column/nav bar (slow network, A/B test), or Twitter DOM changes moved the AppTabBar_Profile_Link selector.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/b3ecde3653ca102b. Report an issue: GitHub.