jackwener/OpenCLI · error · AuthRequiredError

Twitter/X auth cookies are missing

Error message

Twitter/X auth cookies are missing

What it means

verifyTwitterIdentity first checks hasTwitterSessionCookies(page); if the auth_tweet_cookie/auth Cookies are absent it throws AuthRequiredError('x.com', 'Twitter/X auth cookies are missing'). This is a deliberate auth-gate: identity verification cannot proceed without a logged-in session, so the CLI signals that the user must log in to x.com in the controlled browser.

Source

Thrown at clis/twitter/auth.js:56

 * account for a few seconds, so a single read misreports it (#2252); trust
 * the handle only once it holds across three polls.
 */
async function readSettledScreenName(page) {
  const samples = [];
  for (let poll = 0; poll < SCREEN_NAME_POLLS; poll += 1) {
    samples.push(await readScreenName(page));
    if (poll < SCREEN_NAME_POLLS - 1) {
      await page.sleep(SCREEN_NAME_POLL_SECONDS);
    }
  }
  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'],

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Run the x.com login flow (auth login for the twitter site) and complete login in the browser window.
  2. Verify the browser profile the CLI uses is the one where you actually logged in.
  3. Confirm cookies are not being wiped between runs (e.g. incognito mode or cleanup scripts).
  4. Manually open x.com in the controlled browser and confirm you stay logged in.

Example fix

// before
await cli.run('twitter whoami');
// after
if (!(await hasSessionCookies())) {
  await cli.run('auth login x.com'); // complete login interactively
}
await cli.run('twitter whoami');
Defensive patterns

Strategy: try-catch

Validate before calling

// before invoking identity-requiring commands
const cookies = await getCookies('x.com');
if (!cookies.some((c) => c.name === 'auth_token')) {
  await cli.run('auth login x.com');
}

Type guard

function hasSessionCookie(cookies) {
  return Array.isArray(cookies) && cookies.some((c) => c.name === 'auth_token' && c.value);
}

Try / catch

try {
  await cli.run('twitter whoami');
} catch (e) {
  if (/auth cookies are missing/.test(e.message)) {
    await cli.run('auth login x.com');
    return cli.run('twitter whoami');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling a twitter command that requires identity verification when the browser has no x.com session cookies — fresh profile, cookies cleared, or logged out of x.com.

Common situations: Running the CLI with a brand-new automation browser profile, after clearing cookies/site data, after x.com invalidated the session (password change, security logout), or pointing the CLI at the wrong browser profile directory.

Related errors


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