jackwener/OpenCLI · error · AuthRequiredError

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

Error message

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

What it means

AuthRequiredError raised by `qwen image` when the image-generation prompt cannot be sent because a login gate is detected on the page. Image generation typically requires a stricter/longer-lived session than chat, so an unauthenticated or recently expired session fails at the sendMessage step via hasLoginGate() -> authRequired().

Source

Thrown at clis/qwen/image.js:135

        const startFresh = normalizeBooleanFlag(kwargs.new, true);
        const skipDownload = normalizeBooleanFlag(kwargs.sd, false);
        const timeout = Number(kwargs.timeout ?? 180);
        if (!Number.isInteger(timeout) || timeout <= 0) {
            throw new ArgumentError('timeout must be a positive integer');
        }

        await ensureOnQianwen(page);
        await dismissLoginModal(page);
        if (startFresh) {
            await startNewChat(page);
            await dismissLoginModal(page);
        }
        await setFeatureToggle(page, 'image', true);
        await page.wait(0.5);

        const send = await sendMessage(page, prompt);
        if (!send?.ok) {
            if (await hasLoginGate(page)) throw authRequired();
            throw new CommandExecutionError(send?.reason || 'Failed to send Qianwen image prompt');
        }

        // Grab the newest assistant bubble id after send by polling briefly
        let targetId = '';
        for (let i = 0; i < 5; i += 1) {
            await page.wait(1);
            const bubbles = await getMessageBubbles(page);
            const lastAnswer = [...bubbles].reverse().find((b) => b.role === 'Assistant');
            if (lastAnswer) { targetId = lastAnswer.id; break; }
        }

        const waitResult = await waitForImageUrls(page, targetId, timeout);
        const link = await page.evaluate('window.location.href').catch(() => 'https://www.qianwen.com/');
        if (waitResult.status === 'auth_required') throw authRequired();
        if (waitResult.status === 'timeout') {
            throw new TimeoutError('qianwen image', timeout, 'No generated images observed before timeout.');
        }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Scan the QR code with the Qianwen APP to log in at qianwen.com in the automation browser, then rerun `qwen image`
  2. Log in once interactively and persist the profile directory so subsequent image runs reuse the session
  3. If the send failure is not actually a login gate, check hasLoginGate's selectors against the current qianwen.com UI (false positives surface as this error)
  4. Retry shortly after logging in — new sessions sometimes need one page reload before the composer accepts input

Example fix

// before
const send = await sendMessage(page, prompt);
if (!send?.ok) {
  if (await hasLoginGate(page)) throw authRequired();
// after (caller pre-check)
if (!(await isQianwenLoggedIn(page))) {
  await promptQrLogin(); // avoid failing mid-image-run
}
const send = await sendMessage(page, prompt);
Defensive patterns

Strategy: validation

Validate before calling

async function assertQianwenLoggedIn(page) {
  const gate = await page.evaluate(() => !!document.querySelector('[class*=login-wall], [class*=login-modal]'));
  if (gate) throw new Error('Login required before image generation — scan QR with Qianwen APP');
}

Try / catch

try {
  await qwenImage(prompt);
} catch (e) {
  if (isAuthError(e)) { await ensureQianwenLogin(); return qwenImage(prompt); }
  throw e;
}

Prevention

When it happens

Trigger: `qwen image` toggles the image feature, calls sendMessage(page, prompt), the send fails (send.ok is falsy), and hasLoginGate(page) then finds a login wall/modal on qianwen.com.

Common situations: Generating images without ever logging in in that browser profile; session expired between runs (image runs are long, cookies may lapse); qianwen.com demanding re-login before allowing image features.

Related errors


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