jackwener/OpenCLI · error · AuthRequiredError

请在浏览器里用千问 APP 扫码登录 qianwen.com 后再重试。

Error message

请在浏览器里用千问 APP 扫码登录 qianwen.com 后再重试。

What it means

AuthRequiredError thrown by `qwen history` when the session-list API (chat2-api.qianwen.com) responds with HTTP 401 or 403, i.e. the backend rejected the request as unauthenticated. The CLI maps those statuses directly to authRequired() (clis/qwen/history.js:50) with the standard QR-scan guidance.

Source

Thrown at clis/qwen/history.js:46

    navigateBefore: false,
    args: [
        { name: 'limit', type: 'int', default: 20, help: 'Max conversations to show (default 20, max 100)' },
    ],
    columns: ['Index', 'Title', 'Updated', 'Url'],
    func: async (page, kwargs) => {
        const limit = Number(kwargs.limit ?? 20);
        if (!Number.isInteger(limit) || limit <= 0) {
            throw new ArgumentError('limit must be a positive integer');
        }
        if (limit > 100) {
            throw new ArgumentError('limit must be <= 100');
        }
        await ensureOnQianwen(page);
        await dismissLoginModal(page);
        await page.wait(1);
        const result = await getSessionListFromApi(page, limit);
        if (!result.ok) {
            if (result.status === 401 || result.status === 403) throw authRequired();
            if (!result.sessions.length) {
                throw new CommandExecutionError(`Qianwen history API failed (status=${result.status}) ${result.error || ''}`.trim());
            }
        }
        if (!result.sessions.length) {
            throw new EmptyResultError('qwen history', 'No Qianwen conversations found.');
        }
        return result.sessions.slice(0, limit).map((s, i) => ({
            Index: i + 1,
            Title: s.title || '(untitled)',
            Updated: formatDate(s.updated_at),
            Url: `https://www.qianwen.com/chat/${s.id}`,
        }));
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Log into qianwen.com via QR scan with the Qianwen APP in the automation browser, then rerun `qwen history`
  2. Verify the API request is being sent with the correct cookies/headers (inspect getSessionListFromApi) — a missing credential header can also yield 401
  3. Retry after a delay if 403 appears without a login wall (possible rate-limit or WAF block)
  4. Persist the browser profile to keep auth cookies across invocations

Example fix

// before
const result = await getSessionListFromApi(page, limit);
if (!result.ok && (result.status === 401 || result.status === 403)) throw authRequired();
// after (caller)
try {
  await qwenHistory(limit);
} catch (e) {
  if (e.code === 'AUTH_REQUIRED') {
    await interactiveQianwenLogin();
    await qwenHistory(limit);
  } else throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

const probe = await page.evaluate(() => fetch('https://chat2-api.qianwen.com/__probe', { method: 'HEAD' }).then(r => r.status).catch(() => 0));
if (probe === 401 || probe === 403) throw new Error('Qianwen session invalid — re-login before listing history');

Type guard

function isUnauthorized(res) { return res && (res.status === 401 || res.status === 403); }

Try / catch

try {
  await qwenHistory(limit);
} catch (e) {
  if (isAuthError(e)) { await qrRelogin(); return qwenHistory(limit); }
  throw e;
}

Prevention

When it happens

Trigger: `qwen history` calls getSessionListFromApi and receives status 401 or 403 — the browser's Qianwen cookies are missing, expired, or not accepted by the API domain.

Common situations: Cookie expired since last run; API domain (chat2-api.qianwen.com) requires a fresher token than the web session holds; region/edge serving 403 for suspicious traffic; user cleared cookies in the shared profile.

Related errors


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