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
- Log into qianwen.com via QR scan with the Qianwen APP in the automation browser, then rerun `qwen history`
- Verify the API request is being sent with the correct cookies/headers (inspect getSessionListFromApi) — a missing credential header can also yield 401
- Retry after a delay if 403 appears without a login wall (possible rate-limit or WAF block)
- 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
- Re-login whenever cookies are older than the typical Qianwen session lifetime
- Persist the profile directory so auth cookies survive CLI restarts
- Handle 403-without-login-wall as rate limiting and back off before retrying
- Don't clear browser storage between commands in a send->history sequence
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
- Gmail ${operation} returned HTTP ${status}
- 未登录或登录已过期,请先在浏览器中登录贝壳找房
- LinkedIn Learning auth failed (HTTP ${result.status ?? ''}).
- MiniMax ${region.host} rejected ${MINIMAX_API_KEY_VAR} (HTTP
- NotebookLM RPC returned auth error (${errorCode})
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/a18f7b10e0feed57.
Report an issue: GitHub.