{"record":{"id":"ab3d653053cd4480","repo":"jackwener/OpenCLI","slug":"xianyu-unb-tracknick-cookie-missing-anonymous","errorCode":null,"errorMessage":"Xianyu unb/tracknick cookie missing — anonymous","messagePattern":"Xianyu unb/tracknick cookie missing — anonymous","errorType":"error_code","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/xianyu/auth.js","lineNumber":11,"sourceCode":"import { AuthRequiredError, CommandExecutionError } from '@jackwener/opencli/errors';\nimport { registerSiteAuthCommands } from '../_shared/site-auth.js';\n\nasync function hasXianyuIdentityCookie(page) {\n  const cookies = await page.getCookies({ url: 'https://www.goofish.com' });\n  return cookies.some(c => (c.name === 'unb' || c.name === 'tracknick') && c.value);\n}\n\nasync function verifyXianyuIdentity(page) {\n  if (!await hasXianyuIdentityCookie(page)) {\n    throw new AuthRequiredError('goofish.com', 'Xianyu unb/tracknick cookie missing — anonymous');\n  }\n  await page.goto('https://www.goofish.com/personal');\n  await page.wait(2);\n  const finalUrl = await page.evaluate(`location.href`);\n  if (/passport\\.(taobao|goofish)\\.com\\/(member\\/login|login)/.test(String(finalUrl || ''))) {\n    throw new AuthRequiredError('goofish.com', `Xianyu /personal redirected to login: ${finalUrl}`);\n  }\n  const cookies = await page.getCookies({ url: 'https://www.goofish.com' });\n  const tracknick = cookies.find(c => c.name === 'tracknick')?.value || '';\n  const unb = cookies.find(c => c.name === 'unb')?.value || '';\n  const probe = await page.evaluate(`\n    (() => {\n      const bodyText = document.body?.innerText || '';\n      const requiresAuth = /请先登录|登录后/.test(bodyText);\n      const blocked = /验证码|安全验证|异常访问/.test(bodyText);\n      const nick = document.querySelector('.user-name, .user-nick, .nick, [class*=\"nickname\"]')?.innerText?.trim() || '';\n      const html = document.body?.innerHTML || '';\n      const userIdMatch = html.match(/['\"]?userId['\"]?\\\\s*[:=]\\\\s*['\"]?(\\\\d+)/i);","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xianyu/auth.js#L1-L29","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run the xianyu login command to open an interactive browser session and log in to goofish.com.","Complete login manually in the opened browser window until the personal page loads.","Confirm the persistent browser profile the CLI uses is the one you logged in with (check profile path config).","Re-check cookies for goofish.com in that profile after login; re-login if unb/tracknick are absent."],"exampleFix":"// before (headless script with no login step)\nawait page.goto('https://www.goofish.com/personal');\n// after\nconst ok = await quickCheck(page); // hasXianyuIdentityCookie\nif (!ok) await runInteractiveLogin('xianyu'); // sets unb/tracknick cookies\nawait verifyXianyuIdentity(page);","handlingStrategy":"validation","validationCode":"const cookies = await page.getCookies({ url: 'https://www.goofish.com' });\nconst loggedIn = cookies.some(c => (c.name === 'unb' || c.name === 'tracknick') && c.value);\nif (!loggedIn) {\n  await runInteractiveLogin('xianyu'); // https://www.goofish.com/login\n}","typeGuard":"function hasIdentityCookie(cookies) {\n  return Array.isArray(cookies) && cookies.some(\n    c => (c.name === 'unb' || c.name === 'tracknick') && typeof c.value === 'string' && c.value.length > 0\n  );\n}","tryCatchPattern":"try {\n  await verifyXianyuIdentity(page);\n} catch (err) {\n  if (/cookie missing/.test(err.message)) {\n    await runInteractiveLogin('xianyu');\n    await verifyXianyuIdentity(page); // retry once after login\n  } else throw err;\n}","preventionTips":["Always run a quick cookie check (unb/tracknick) before any authenticated xianyu operation.","Use a persistent browser profile dedicated to the CLI and log in there once.","Don't run cookie cleaners/scheduled wipes against the CLI's profile directory.","Handle AuthRequiredError by launching the login flow rather than failing the whole script."],"tags":["authentication","cookies","goofish","xianyu"],"backgroundTag":"auth-cookie-missing","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}