jackwener/OpenCLI · error · AuthRequiredError
Not logged into x.com (no ct0 cookie)
Error message
Not logged into x.com (no ct0 cookie)
What it means
The list-create command authenticates to x.com by reading the ct0 CSRF cookie from the browser session. If no ct0 cookie exists after navigating to https://x.com, the user is not logged in, so the command throws AuthRequiredError instead of making authenticated GraphQL calls that would fail anyway.
Source
Thrown at clis/twitter/list-create.js:115
description: 'Create a new Twitter/X list (returns the new list id)',
access: 'write',
domain: 'x.com',
strategy: Strategy.COOKIE,
browser: true,
args: [
{ name: 'name', positional: true, type: 'string', required: true, help: `List name (max ${NAME_MAX} chars)` },
{ name: 'description', type: 'string', default: '', help: `Optional list description (max ${DESCRIPTION_MAX} chars)` },
{ name: 'mode', type: 'string', default: 'public', help: 'public | private' },
],
columns: ['id', 'name', 'description', 'mode', 'status'],
func: async (page, kwargs) => {
const { listName: name, listDescription: description, listMode: mode, privateFlag: isPrivate } = parseListCreateArgs(kwargs);
await page.goto('https://x.com');
await page.wait(3);
const cookies = await page.getCookies({ url: 'https://x.com' });
const ct0 = cookies.find((c) => c.name === 'ct0')?.value || null;
if (!ct0) throw new AuthRequiredError('x.com', 'Not logged into x.com (no ct0 cookie)');
// Hardcode queryId: it must match the FEATURES schema below.
// Letting resolveTwitterQueryId() drift would pull a newer queryId
// whose schema would reject our simplified features payload.
const queryId = CREATE_LIST_QUERY_ID;
const headers = JSON.stringify({
'Authorization': `Bearer ${decodeURIComponent(TWITTER_BEARER_TOKEN)}`,
'X-Csrf-Token': ct0,
'X-Twitter-Auth-Type': 'OAuth2Session',
'X-Twitter-Active-User': 'yes',
'Content-Type': 'application/json',
});
const body = JSON.stringify({
variables: { isPrivate, name, description },
features: FEATURES,
queryId,
});View on GitHub (pinned to 49907e53dc)
Solutions
- Log into x.com in the automation browser session, then re-run the command
- Re-run `opencli` login/session bootstrap for Twitter if the CLI provides one
- Check you are using the same browser profile that holds the x.com session
- Clear corrupted cookies and log in again if ct0 is stale
Example fix
// before opencli twitter list-create "My List" // after opencli twitter login # establish x.com session first opencli twitter list-create "My List"
Defensive patterns
Strategy: try-catch
Validate before calling
const cookies = await page.getCookies({ url: 'https://x.com' });
const hasCt0 = cookies.some((c) => c.name === 'ct0' && c.value);
if (!hasCt0) throw new Error('Not logged into x.com — run login first'); Type guard
function isLoggedIn(cookies) {
return Array.isArray(cookies) && cookies.some((c) => c.name === 'ct0' && !!c.value);
} Try / catch
try {
await runListCreate(page, kwargs);
} catch (e) {
if (e instanceof AuthRequiredError && /ct0/.test(e.message)) {
console.error('Run `opencli twitter login` and retry.');
process.exitCode = 2;
} else throw e;
} Prevention
- Log into x.com once per automation profile and reuse it
- Check login state at script start before batch operations
- Treat AuthRequiredError as a distinct exit code in CI
When it happens
Trigger: page.getCookies({ url: 'https://x.com' }) returns no cookie named 'ct0' after page.goto('https://x.com') — i.e. no active x.com session in the automation browser.
Common situations: Running the CLI without ever logging into x.com in the automation browser; session expired/logged out; cookies cleared or isolated browser profile; incognito profile without stored cookies.
Related errors
- Not logged into x.com (no ct0 cookie)
- Not logged into x.com (no ct0 cookie)
- Not logged into x.com (no ct0 cookie)
- 12306 tk auth cookie missing
- Bilibili ${label} API requires login or permission: ${messag
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/2bd226df788650c8.
Report an issue: GitHub.