jackwener/OpenCLI · error · AuthRequiredError

Xianyu blocked by verification / risk control

Error message

Xianyu blocked by verification / risk control

What it means

As a final check, verifyXianyuIdentity probes the rendered /personal page DOM for risk-control signals. If the body text contains 验证码 (captcha), 安全验证 (security verification), or 异常访问 (abnormal access), an AuthRequiredError with 'Xianyu blocked by verification / risk control' is thrown. This means Goofish/Taobao's anti-bot system flagged the session or the automated browser, not that credentials are wrong.

Source

Thrown at clis/xianyu/auth.js:34

  if (/passport\.(taobao|goofish)\.com\/(member\/login|login)/.test(String(finalUrl || ''))) {
    throw new AuthRequiredError('goofish.com', `Xianyu /personal redirected to login: ${finalUrl}`);
  }
  const cookies = await page.getCookies({ url: 'https://www.goofish.com' });
  const tracknick = cookies.find(c => c.name === 'tracknick')?.value || '';
  const unb = cookies.find(c => c.name === 'unb')?.value || '';
  const probe = await page.evaluate(`
    (() => {
      const bodyText = document.body?.innerText || '';
      const requiresAuth = /请先登录|登录后/.test(bodyText);
      const blocked = /验证码|安全验证|异常访问/.test(bodyText);
      const nick = document.querySelector('.user-name, .user-nick, .nick, [class*="nickname"]')?.innerText?.trim() || '';
      const html = document.body?.innerHTML || '';
      const userIdMatch = html.match(/['"]?userId['"]?\\s*[:=]\\s*['"]?(\\d+)/i);
      return { requiresAuth, blocked, domNick: nick, domUserId: userIdMatch?.[1] || '' };
    })()
  `);
  if (probe.blocked) {
    throw new AuthRequiredError('goofish.com', 'Xianyu blocked by verification / risk control');
  }
  if (probe.requiresAuth) {
    throw new AuthRequiredError('goofish.com', 'Xianyu /personal shows login prompt — anonymous');
  }
  const userId = probe.domUserId || unb;
  let decodedTracknick = '';
  if (tracknick) {
    try {
      decodedTracknick = JSON.parse('"' + tracknick.replace(/\\/g, '\\\\') + '"');
    } catch {
      decodedTracknick = tracknick;
    }
  }
  const nickname = probe.domNick || decodedTracknick;
  if (!userId && !nickname) {
    throw new CommandExecutionError('Xianyu /personal rendered but no user identity extractable — stale unb or layout drift');
  }
  return { user_id: String(userId), nickname: String(nickname) };

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Open the visible browser window and manually complete the captcha/security verification, then re-run the command.
  2. Wait and retry later with much lower request frequency; add random delays between page loads.
  3. Use a residential IP / disable VPN or proxy; switch network if the current IP is flagged.
  4. Make the automation profile less detectable (real user profile, non-headless, normal viewport/UA) or use a manually logged-in persistent profile.
  5. If blocked repeatedly, verify the account itself isn't restricted by logging in via a normal browser/app.

Example fix

// before
await page.goto('https://www.goofish.com/personal');
// after
await page.goto('https://www.goofish.com/personal');
if ((await page.evaluate('document.body.innerText')).match(/验证码|安全验证|异常访问/)) {
  await pauseForManualCaptcha(page); // let the user solve it in the visible window
  await page.reload();
}
Defensive patterns

Strategy: fallback

Validate before calling

await page.goto('https://www.goofish.com/personal');
const text = await page.evaluate('document.body?.innerText || ""');
const blocked = /验证码|安全验证|异常访问/.test(text);
if (blocked) {
  // stop automated calls; require manual captcha completion before continuing
  await pauseForManualVerification(page);
}

Type guard

function looksBlocked(probe) {
  return Boolean(probe && typeof probe.blocked === 'boolean' && probe.blocked);
}

Try / catch

try {
  const identity = await verifyXianyuIdentity(page);
} catch (err) {
  if (/risk control|verification/.test(err.message)) {
    await promptUserToSolveCaptchaInVisibleBrowser(page); // fallback to manual step
    return verifyXianyuIdentity(page);
  }
  throw err;
}

Prevention

When it happens

Trigger: Loading goofish.com/personal while Goofish's risk control shows a captcha/security-verification/abnormal-access interstitial — typically after unusual request patterns, headless-browser fingerprint detection, datacenter IPs, or too-frequent scrapes.

Common situations: Scraping at high frequency from one IP; running in a detectable headless/automation browser profile; operating from a datacenter/VPN IP Taobao distrusts; shared IP previously flagged; unusually new account making automated requests.

Related errors


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