jackwener/OpenCLI · error · AuthRequiredError

Xianyu unb/tracknick cookie missing — anonymous

Error message

Xianyu unb/tracknick cookie missing — anonymous

What it means

verifyXianyuIdentity in clis/xianyu/auth.js first checks the browser profile's cookies for a non-empty 'unb' or 'tracknick' cookie on goofish.com. If neither exists, the session is anonymous and an AuthRequiredError is thrown to trigger the interactive login flow. This is the library's way of detecting that the user has never logged in (or the cookie store was cleared) before scraping personal data.

Source

Thrown at clis/xianyu/auth.js:11

import { AuthRequiredError, CommandExecutionError } from '@jackwener/opencli/errors';
import { registerSiteAuthCommands } from '../_shared/site-auth.js';

async function hasXianyuIdentityCookie(page) {
  const cookies = await page.getCookies({ url: 'https://www.goofish.com' });
  return cookies.some(c => (c.name === 'unb' || c.name === 'tracknick') && c.value);
}

async function verifyXianyuIdentity(page) {
  if (!await hasXianyuIdentityCookie(page)) {
    throw new AuthRequiredError('goofish.com', 'Xianyu unb/tracknick cookie missing — anonymous');
  }
  await page.goto('https://www.goofish.com/personal');
  await page.wait(2);
  const finalUrl = await page.evaluate(`location.href`);
  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);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Run the xianyu login command to open an interactive browser session and log in to goofish.com.
  2. Complete login manually in the opened browser window until the personal page loads.
  3. Confirm the persistent browser profile the CLI uses is the one you logged in with (check profile path config).
  4. Re-check cookies for goofish.com in that profile after login; re-login if unb/tracknick are absent.

Example fix

// before (headless script with no login step)
await page.goto('https://www.goofish.com/personal');
// after
const ok = await quickCheck(page); // hasXianyuIdentityCookie
if (!ok) await runInteractiveLogin('xianyu'); // sets unb/tracknick cookies
await verifyXianyuIdentity(page);
Defensive patterns

Strategy: validation

Validate before calling

const cookies = await page.getCookies({ url: 'https://www.goofish.com' });
const loggedIn = cookies.some(c => (c.name === 'unb' || c.name === 'tracknick') && c.value);
if (!loggedIn) {
  await runInteractiveLogin('xianyu'); // https://www.goofish.com/login
}

Type guard

function hasIdentityCookie(cookies) {
  return Array.isArray(cookies) && cookies.some(
    c => (c.name === 'unb' || c.name === 'tracknick') && typeof c.value === 'string' && c.value.length > 0
  );
}

Try / catch

try {
  await verifyXianyuIdentity(page);
} catch (err) {
  if (/cookie missing/.test(err.message)) {
    await runInteractiveLogin('xianyu');
    await verifyXianyuIdentity(page); // retry once after login
  } else throw err;
}

Prevention

When it happens

Trigger: Running any xianyu CLI command that requires identity verification when the automated browser profile has no unb/tracknick cookie for https://www.goofish.com — e.g. first run, fresh profile, or cookies cleared/expired.

Common situations: Fresh installation with no prior login; running in CI or a headless environment with an empty browser profile; a privacy cleaner or cookie expiry wiping the Goofish session; logging in on a different browser profile than the one the CLI uses.

Related errors


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