jackwener/OpenCLI · error · AuthRequiredError
12306 tk auth cookie missing
Error message
12306 tk auth cookie missing
What it means
AuthRequiredError thrown when `twitter bookmark-folders` (list command) finds no `ct0` cookie for https://x.com. The command needs the CSRF token from an authenticated session to call the bookmark-folders GraphQL endpoint, so it fails fast before making any request.
Source
Thrown at clis/12306/auth.js:11
import { AuthRequiredError, CommandExecutionError } from '@jackwener/opencli/errors';
import { registerSiteAuthCommands } from '../_shared/site-auth.js';
async function has12306SessionCookie(page) {
const cookies = await page.getCookies({ url: 'https://kyfw.12306.cn' });
return cookies.some(c => c.name === 'tk' && c.value);
}
async function verify12306Identity(page) {
if (!await has12306SessionCookie(page)) {
throw new AuthRequiredError('12306.cn', '12306 tk auth cookie missing');
}
await page.goto('https://kyfw.12306.cn/otn/view/index.html');
await page.wait(2);
const probe = await page.evaluate(`(async () => {
try {
const r = await fetch('/otn/index/initMy12306Api', {
method: 'POST',
credentials: 'include',
headers: { 'X-Requested-With': 'XMLHttpRequest' },
});
if (/login\\.html/.test(r.url)) {
return { kind: 'auth', detail: '12306 initMy12306Api redirected to login' };
}
const t = await r.text();
let d = null;
try { d = JSON.parse(t); } catch {}
if (!d || d.status === false || /未登录|登录超时|NotLogin/i.test(t)) {
return { kind: 'auth', detail: '12306 initMy12306Api returned NotLogin' };View on GitHub (pinned to 49907e53dc)
Solutions
- Log into x.com interactively in the CLI's browser session and retry
- Ensure the CLI uses the persistent profile containing your x.com login
- After login, verify the ct0 cookie exists for x.com (devtools → Application → Cookies)
- Keep the session alive; avoid cookie-clearing extensions or scripts
Example fix
// before opencli twitter bookmark-folders # not logged in // after opencli browser open https://x.com/login # complete login in this profile opencli twitter bookmark-folders
Defensive patterns
Strategy: try-catch
Validate before calling
const cookies = await page.getCookies({ url: 'https://x.com' });
if (!cookies.some(c => c.name === 'ct0')) throw new Error('Not logged into x.com'); Type guard
function hasCt0(cookies) { return Array.isArray(cookies) && cookies.some(c => c && c.name === 'ct0' && typeof c.value === 'string' && c.value.length > 0); } Try / catch
try {
const folders = await opencli('twitter bookmark-folders');
} catch (e) {
if (/no ct0 cookie/.test(e.message)) {
await opencli('browser open', 'https://x.com/login');
// retry after login
}
} Prevention
- Bootstrap login before automated runs
- Persist the browser profile
- Check ct0 cookie presence in preflight checks
- Re-login after x.com forces sign-out
When it happens
Trigger: Running the listing command with a browser session that has never logged into x.com; cookies cleared; wrong browser profile attached; incognito/non-persistent context.
Common situations: CI or scheduled jobs using a fresh browser context; switching machines or profiles; x.com logged the session out due to suspicious activity, purging 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)
- csrftoken cookie missing - make sure you are logged in to In
- csrftoken cookie missing - make sure you are logged in to In
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/bfa40bd633eeb631.
Report an issue: GitHub.