{"record":{"id":"6f1f1e6ce55c3d11","repo":"jackwener/OpenCLI","slug":"xianyu-item-detail-requires-a-logged-in-browser-se","errorCode":null,"errorMessage":"Xianyu item detail requires a logged-in browser session","messagePattern":"Xianyu item detail requires a logged-in browser session","errorType":"error_code","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/xianyu/item.js","lineNumber":125,"sourceCode":"    site: 'xianyu',\n    name: 'item',\n    access: 'read',\n    description: '查看闲鱼商品详情',\n    domain: 'www.goofish.com',\n    strategy: Strategy.COOKIE,\n    navigateBefore: false,\n    browser: true,\n    args: [\n        { name: 'item_id', required: true, positional: true, help: '闲鱼商品 item_id' },\n    ],\n    columns: ['item_id', 'title', 'price', 'condition', 'brand', 'location', 'seller_name', 'want_count'],\n    func: async (page, kwargs) => {\n        const itemId = normalizeNumericId(kwargs.item_id, 'item_id', '1040754408976');\n        await page.goto(buildItemUrl(itemId));\n        await page.wait(2);\n        const result = await page.evaluate(buildFetchItemEvaluate(itemId));\n        if (result?.error === 'auth-required') {\n            throw new AuthRequiredError('www.goofish.com', 'Xianyu item detail requires a logged-in browser session');\n        }\n        if (result?.error === 'blocked') {\n            throw new EmptyResultError('xianyu item', 'Xianyu item detail is blocked by verification or risk control');\n        }\n        if (result?.error === 'mtop-not-ready') {\n            throw selectorError('window.lib.mtop', '闲鱼页面未完成初始化，无法调用商品详情接口');\n        }\n        if (!result || typeof result !== 'object') {\n            throw new EmptyResultError('xianyu item', '闲鱼商品详情接口未返回有效数据');\n        }\n        const errorCode = String(result.error_code || '');\n        const errorMessage = String(result.error_message || '');\n        if (/FAIL_SYS_SESSION_EXPIRED|SESSION_EXPIRED|FAIL_SYS/.test(errorCode) || /FAIL_SYS_SESSION_EXPIRED|SESSION_EXPIRED/.test(errorMessage)) {\n            throw new AuthRequiredError('www.goofish.com', 'Xianyu item detail requires a logged-in browser session');\n        }\n        if (result.error) {\n            throw new EmptyResultError('xianyu item', errorMessage || `Xianyu item detail request failed: ${result.error}`);\n        }","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xianyu/item.js#L107-L143","documentation":"The `xianyu item` command drives a logged-in browser to www.goofish.com and calls the mtop item-detail API via page.evaluate. When the in-page script reports `error: 'auth-required'`, the library throws AuthRequiredError for domain 'www.goofish.com' — the mtop API rejected the call because the browser session has no valid logged-in cookies. The error carries a hint telling you to open Chrome/Chromium and log in to the site, and exits with the NOPERM code.","triggerScenarios":"Running `xianyu item --item-id <id>` when the underlying browser profile has no goofish.com login cookies, the session cookie is absent/expired, or the mtop response indicates a session-expired/auth failure (`auth-required` from the evaluate result).","commonSituations":"Running the CLI in headless/CI environments where no one ever logged into goofish.com; cookies cleared or rotated by the browser; Xianyu server-side invalidated the session (risk control, long idle); pointing at a fresh browser profile directory.","solutions":["Open Chrome/Chromium with the same profile the CLI uses and log in to https://www.goofish.com manually.","Verify login persisted by re-running the command — mtop now carries valid session cookies.","In automation, complete a one-time interactive login before headless runs, and refresh the session when it expires.","Catch code 'AUTH_REQUIRED' in scripts and prompt for re-login instead of retrying."],"exampleFix":"// before\nconst detail = await cli.run(['xianyu', 'item', '--item-id', '1040754408976']); // AUTH_REQUIRED in CI\n// after\ntry {\n  const detail = await cli.run(['xianyu', 'item', '--item-id', '1040754408976']);\n} catch (err) {\n  if (err.code === 'AUTH_REQUIRED') {\n    console.error('Run: open browser, log in to https://www.goofish.com, then retry');\n    process.exit(err.exitCode);\n  }\n  throw err;\n}","handlingStrategy":"try-catch","validationCode":"// Pre-check login state before fetching item detail:\nconst who = await cli.run(['xianyu', 'me']).catch(() => null);\nif (!who) throw new Error('Not logged in to goofish.com — log in via browser first');","typeGuard":"function isAuthRequiredError(err) {\n  return err && err.code === 'AUTH_REQUIRED' && err.domain === 'www.goofish.com';\n}","tryCatchPattern":"try {\n  const detail = await cli.run(['xianyu', 'item', '--item-id', itemId]);\n} catch (err) {\n  if (err.code === 'AUTH_REQUIRED') {\n    console.error(err.hint); // 'open Chrome and log in to https://www.goofish.com'\n    return null;\n  }\n  throw err;\n}","preventionTips":["Always verify the browser profile has an active goofish.com session before automated runs.","Do a one-time interactive login before switching to headless/CI execution.","Watch for AUTH_REQUIRED as a signal to refresh cookies rather than retrying.","Keep a dedicated, persistent browser profile so cookies survive restarts."],"tags":["auth","xianyu","session","login-required"],"backgroundTag":"site-login-required","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}