{"record":{"id":"87976e04a1448962","repo":"jackwener/OpenCLI","slug":"douban-dbcl2-ck-cookies-missing","errorCode":null,"errorMessage":"Douban dbcl2 / ck cookies missing","messagePattern":"Douban dbcl2 / ck cookies missing","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/douban/auth.js","lineNumber":21,"sourceCode":"\nasync function hasDoubanSessionCookie(page) {\n  const cookies = await page.getCookies({ url: 'https://www.douban.com' });\n  const names = new Set(cookies.map(c => c.name));\n  return names.has('dbcl2') || names.has('ck');\n}\n\nfunction parseDoubanUserId(value) {\n  const text = String(value ?? '');\n  return text.match(/(?:^|\\/)people\\/(\\d+)\\/?/)?.[1]\n    || text.match(/^\"?(\\d+):/)?.[1]\n    || '';\n}\n\nasync function verifyDoubanIdentity(page) {\n  const cookies = await page.getCookies({ url: 'https://www.douban.com' });\n  const names = new Set(cookies.map(c => c.name));\n  if (!names.has('dbcl2') && !names.has('ck')) {\n    throw new AuthRequiredError('douban.com', 'Douban dbcl2 / ck cookies missing');\n  }\n  const cookieUid = parseDoubanUserId(cookies.find(c => c.name === 'dbcl2')?.value);\n  await page.goto('https://www.douban.com/mine/');\n  await page.wait(2);\n  const probe = await page.evaluate(`\n    (() => {\n      const parseUid = (value) => String(value || '').match(/(?:^|\\\\/)people\\\\/(\\\\d+)\\\\/?/)?.[1] || '';\n      const currentUrl = new URL(window.location.href);\n      if (currentUrl.hostname === 'accounts.douban.com' || currentUrl.pathname.startsWith('/passport/')) {\n        return { kind: 'auth', detail: 'Douban /mine redirected to the login flow' };\n      }\n      const navUser = document.querySelector('.nav-user-account .bn-more, .top-nav-info a.bn-more');\n      const navHref = navUser?.getAttribute('href') || navUser?.href || '';\n      const user_id = parseUid(window.location.href) || parseUid(navHref);\n      const name = (navUser?.textContent || document.querySelector('.info h1, h1')?.textContent || '').trim();\n      return user_id\n        ? { ok: true, user_id, name }\n        : { kind: 'unknown', detail: 'Douban user_id parse failed: href=' + navHref + ' location=' + window.location.href };","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/douban/auth.js#L3-L39","documentation":"verifyDoubanIdentity inspects the browser's cookies for douban.com and requires an authenticated session, detected via the dbcl2 or ck cookies set after Douban login. It throws AuthRequiredError when neither cookie exists, meaning the reused browser profile is not logged in to douban.com.","triggerScenarios":"Running any authenticated douban command with a fresh/incognito browser profile; after clearing cookies; on a machine whose browser was never signed in to douban.com; after Douban session expiry removed the cookies.","commonSituations":"CI or headless environments with no logged-in profile; switching browser profiles; a long-lived session silently expiring so the cookies disappear.","solutions":["Run the douban login flow (opencli site auth for douban) and sign in at accounts.douban.com/passport/login in the reused browser","Manually log in to douban.com in the browser profile opencli reuses, then rerun","Verify cookies exist: document.cookie or devtools on www.douban.com should show dbcl2 or ck"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const cookies = await page.getCookies({ url: 'https://www.douban.com' });\nconst ok = cookies.some(c => c.name === 'dbcl2' || c.name === 'ck');\nif (!ok) console.error('Not logged in to douban.com — run the login flow first');","typeGuard":"function hasDoubanCookies(cookies) { return cookies.some(c => c.name === 'dbcl2' || c.name === 'ck'); }","tryCatchPattern":"try { await verifyDoubanIdentity(page); } catch (e) { if (e instanceof AuthRequiredError) { await runDoubanLogin(); return verifyDoubanIdentity(page); } throw e; }","preventionTips":["Run the login/auth check before batch jobs","Persist and reuse the same browser profile that holds the douban session","Detect 'Waiting for dbcl2 / ck cookies' polls and surface a login prompt"],"tags":["auth","cookies","douban","login-required"],"backgroundTag":"auth-cookies-missing","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}