{"record":{"id":"5c7f1244dfdecf94","repo":"jackwener/OpenCLI","slug":"auth-required-5c7f12","errorCode":"AUTH_REQUIRED","errorMessage":"Yuanbao opened a login gate when navigating to the conversation.","messagePattern":"Yuanbao opened a login gate when navigating to the conversation\\.","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/yuanbao/detail.js","lineNumber":37,"sourceCode":"    strategy: Strategy.COOKIE,\n    browser: true,\n    siteSession: 'persistent',\n    navigateBefore: false,\n    args: [\n        {\n            name: 'id',\n            positional: true,\n            required: true,\n            help: 'Full https://yuanbao.tencent.com/chat/<agentId>/<convId> URL or \"<agentId>/<convId>\" pair (a UUID alone is not enough — Yuanbao requires the agent slug)',\n        },\n    ],\n    columns: ['Role', 'Text'],\n    func: async (page, kwargs) => {\n        const { agentId, convId } = parseYuanbaoSessionId(kwargs.id);\n        await page.goto(`${YUANBAO_URL}chat/${agentId}/${convId}`, { waitUntil: 'load', settleMs: 2500 });\n        await page.wait(2);\n        if (await hasLoginGate(page)) {\n            throw authRequired('Yuanbao opened a login gate when navigating to the conversation.');\n        }\n\n        // Poll up to ~20s for the transcript to render. The page shell loads\n        // before history is fetched, so a fixed wait races the empty render.\n        let bubbles = [];\n        const POLL_DEADLINE_MS = 20_000;\n        const POLL_INTERVAL_S = 1;\n        const startedAt = Date.now();\n        while (Date.now() - startedAt < POLL_DEADLINE_MS) {\n            bubbles = await getYuanbaoMessageBubbles(page);\n            if (bubbles.length > 0) break;\n            await page.wait(POLL_INTERVAL_S);\n        }\n\n        if (!bubbles.length) {\n            throw new EmptyResultError(\n                'yuanbao detail',\n                `No visible messages found for conversation ${agentId}/${convId}. Verify the IDs are correct and that the session belongs to the current login.`,","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/yuanbao/detail.js#L19-L55","documentation":"Navigating to a Yuanbao conversation URL landed on a login gate instead of the transcript, so the detail command throws AUTH_REQUIRED immediately after page load. The conversation history cannot be read without an authenticated session.","triggerScenarios":"Running the yuanbao detail command when, after page.goto to YUANBAO_URL chat/<agentId>/<convId>, hasLoginGate(page) returns true.","commonSituations":"Shared/exported session id whose cookies belong to a logged-out browser; expired session cookies; conversation belonging to an account that must log in to view history; Yuanbao requiring login for all deep links.","solutions":["Log into Yuanbao in the automation browser profile, then retry the detail command","Clear Yuanbao cookies and perform a fresh login so deep links resolve to the transcript","Confirm the convId/agentId belong to the logged-in account (parseYuanbaoSessionId only validates format)","Check whether the conversation is private/deleted — gates can appear for inaccessible conversations"],"exampleFix":"// before: navigating without ensuring login\nawait page.goto(convUrl, { waitUntil: 'load' });\n// after: catch auth error and re-login\ntry {\n  const conv = await yuanbaoDetail(id);\n} catch (e) {\n  if (e.code === 'AUTH_REQUIRED') { await yuanbaoLogin(); return yuanbaoDetail(id); }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"import { hasLoginGate } from './yuanbao/page.js';\nawait page.goto(convUrl, { waitUntil: 'load' });\nif (await hasLoginGate(page)) { await yuanbaoLogin(page); }","typeGuard":"function isValidYuanbaoSessionId(id) {\n  return typeof id === 'string' && /^(agent-)?[\\w-]+\\/[\\w-]+$/.test(id);\n}","tryCatchPattern":"try {\n  return await yuanbaoDetail(id);\n} catch (e) {\n  if (e.code === 'AUTH_REQUIRED') { await yuanbaoLogin(page); return yuanbaoDetail(id); }\n  throw e;\n}","preventionTips":["Ensure the browser profile is logged in before deep-link navigation","Verify the conversation id belongs to the authenticated account","Re-login when cookies age out; deep links require full auth","Catch AUTH_REQUIRED around all yuanbao commands and centralize re-login logic"],"tags":["auth","browser-automation","yuanbao"],"backgroundTag":"login-gate-detected","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}