jackwener/OpenCLI · error · CliError

AUTH_REQUIRED

AUTH_REQUIRED

Error message

Douban requires a logged-in browser session before these commands can load data.

What it means

ensureDoubanReady loads a douban page and inspects its state: a sec.douban.com redirect, a login-jump title, or an '异常请求' (abnormal request) body means douban is blocking unauthenticated access. It throws CliError with code AUTH_REQUIRED because all data commands need a logged-in browser session.

Source

Thrown at clis/douban/utils.js:94

    if (!match) {
        return { title: normalized, originalTitle: '' };
    }
    return {
        title: normalizeText(match[1]),
        originalTitle: normalizeText(match[2]),
    };
}
async function ensureDoubanReady(page) {
    const state = await page.evaluate(`
    (() => {
      const title = (document.title || '').trim();
      const href = (location.href || '').trim();
      const blocked = href.includes('sec.douban.com') || /登录跳转/.test(title) || /异常请求/.test(document.body?.innerText || '');
      return { blocked, title, href };
    })()
  `);
    if (state?.blocked) {
        throw new CliError('AUTH_REQUIRED', 'Douban requires a logged-in browser session before these commands can load data.', 'Please sign in to douban.com in the browser that opencli reuses, then rerun the command.');
    }
}
function isDetachedPageError(error) {
    const message = error instanceof Error ? error.message : String(error || '');
    return /Detached while handling command|Debugger is not attached to the tab|Target closed|No tab with id/i.test(message);
}
async function withDetachedRetry(task, options = {}) {
    const attempts = Math.max(1, options.attempts || 2);
    let lastError;
    for (let attempt = 0; attempt < attempts; attempt += 1) {
        try {
            return await task();
        }
        catch (error) {
            lastError = error;
            if (attempt >= attempts - 1 || !isDetachedPageError(error)) {
                throw error;
            }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Sign in to douban.com in the browser profile opencli reuses, then rerun the command
  2. Run the douban site-auth/login command to open the login page and authenticate
  3. If blocked at sec.douban.com despite login, solve the challenge manually in the browser and retry after a pause
Defensive patterns

Strategy: try-catch

Validate before calling

await page.goto('https://www.douban.com/mine/');
const authed = !page.url().includes('sec.douban.com') && !page.url().includes('accounts.douban.com');
if (!authed) console.error('Log in to douban.com in the reused browser before running data commands');

Type guard

function doubanBlockedState(state) { return state && state.blocked === true; }

Try / catch

try { await doubanData(cmd, args); } catch (e) { if (e.code === 'AUTH_REQUIRED') { await openDoubanLoginAndWait(); return doubanData(cmd, args); } throw e; }

Prevention

When it happens

Trigger: Hitting douban data endpoints (subject pages, book/movie hot lists) from an anonymous browser profile; douban risk-control redirecting to sec.douban.com; a previously valid session fully expired.

Common situations: First run on a new machine/profile; headless automation without prior manual login; heavy scraping triggering douban's anti-bot gate even for previously valid sessions.

Related errors


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