{"record":{"id":"4faf2c9fa8c34438","repo":"jackwener/OpenCLI","slug":"xianyu-personal-shows-login-prompt-anonymous","errorCode":null,"errorMessage":"Xianyu /personal shows login prompt — anonymous","messagePattern":"Xianyu /personal shows login prompt — anonymous","errorType":"error_code","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/xianyu/auth.js","lineNumber":37,"sourceCode":"  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);\n      return { requiresAuth, blocked, domNick: nick, domUserId: userIdMatch?.[1] || '' };\n    })()\n  `);\n  if (probe.blocked) {\n    throw new AuthRequiredError('goofish.com', 'Xianyu blocked by verification / risk control');\n  }\n  if (probe.requiresAuth) {\n    throw new AuthRequiredError('goofish.com', 'Xianyu /personal shows login prompt — anonymous');\n  }\n  const userId = probe.domUserId || unb;\n  let decodedTracknick = '';\n  if (tracknick) {\n    try {\n      decodedTracknick = JSON.parse('\"' + tracknick.replace(/\\\\/g, '\\\\\\\\') + '\"');\n    } catch {\n      decodedTracknick = tracknick;\n    }\n  }\n  const nickname = probe.domNick || decodedTracknick;\n  if (!userId && !nickname) {\n    throw new CommandExecutionError('Xianyu /personal rendered but no user identity extractable — stale unb or layout drift');\n  }\n  return { user_id: String(userId), nickname: String(nickname) };\n}\n\nregisterSiteAuthCommands({","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xianyu/auth.js#L19-L55","documentation":"verifyXianyuIdentity probes the logged-in goofish.com /personal page; if the page renders but shows a login prompt instead of the user profile, the session is anonymous. The library throws AuthRequiredError because identity (unb/tracknick cookies) cannot be verified without an authenticated session.","triggerScenarios":"Calling verifyXianyuIdentity (or any xianyu auth-verify flow) when the browser page has no valid login session; probe.requiresAuth is true because /personal redirected to or displayed a login prompt.","commonSituations":"Cookies expired or were cleared; user logged out of goofish.com; automation runs in a fresh browser profile that never logged in; goofish risk control invalidated the session.","solutions":["Open https://www.goofish.com/login in the automated browser and log in manually or restore saved cookies","Re-run verifyXianyuIdentity after the session is established","Ensure persistent user-data-dir is used so cookies survive restarts","Check that unb and tracknick cookies are present before verification"],"exampleFix":"// before\nconst id = await verifyXianyuIdentity(page); // throws if anonymous\n// after\nif (await hasXianyuIdentityCookie(page)) {\n  const id = await verifyXianyuIdentity(page);\n} else {\n  await loginManuallyOrRestoreCookies(page);\n}","handlingStrategy":"try-catch","validationCode":"const cookies = await page.context().cookies('https://www.goofish.com');\nconst authed = cookies.some(c => c.name === 'unb') && cookies.some(c => c.name === 'tracknick');\nif (!authed) await loginXianyu(page);","typeGuard":"function isAuthRequiredError(e) {\n  return e instanceof AuthRequiredError || e?.name === 'AuthRequiredError';\n}","tryCatchPattern":"try {\n  const identity = await verifyXianyuIdentity(page);\n} catch (e) {\n  if (isAuthRequiredError(e)) {\n    await openLoginAndAwaitSession(page, 'https://www.goofish.com/login');\n    return verifyXianyuIdentity(page);\n  }\n  throw e;\n}","preventionTips":["Use a persistent browser user-data-dir so cookies survive restarts","Check unb/tracknick cookies before every authenticated xianyu call","Refresh the session periodically to avoid mid-task expiry"],"tags":["auth","xianyu","session-expired"],"backgroundTag":"auth-session-required","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}