{"record":{"id":"c5044ee445207a87","repo":"jackwener/OpenCLI","slug":"taobao-tracknick-cookie-absent-after-navigation","errorCode":null,"errorMessage":"Taobao tracknick cookie absent after navigation","messagePattern":"Taobao tracknick cookie absent after navigation","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/taobao/auth.js","lineNumber":22,"sourceCode":"async function hasTaobaoSessionCookie(page) {\n  const cookies = await page.getCookies({ url: 'https://www.taobao.com' });\n  return cookies.some(c => c.name === 'tracknick' && c.value);\n}\n\nasync function verifyTaobaoIdentity(page) {\n  if (!await hasTaobaoSessionCookie(page)) {\n    throw new AuthRequiredError('taobao.com', 'Taobao tracknick cookie missing — anonymous');\n  }\n  await page.goto('https://i.taobao.com/my_itaobao');\n  await page.wait(2);\n  const finalUrl = await page.evaluate(`location.href`);\n  if (/login\\.taobao\\.com\\/member\\/login/.test(String(finalUrl || ''))) {\n    throw new AuthRequiredError('taobao.com', `Taobao my_itaobao redirected to login: ${finalUrl}`);\n  }\n  const cookies = await page.getCookies({ url: 'https://www.taobao.com' });\n  const tracknick = cookies.find(c => c.name === 'tracknick')?.value || '';\n  if (!tracknick) {\n    throw new AuthRequiredError('taobao.com', 'Taobao tracknick cookie absent after navigation');\n  }\n  const domInfo = await page.evaluate(`\n    (() => {\n      const nick = (document.querySelector('.user-nick, .site-nav-user, .user-name')?.innerText || '').trim();\n      const html = document.body?.innerHTML || '';\n      const userIdMatch = html.match(/userId[\\\"'\\\\s:=]+(\\\\d+)/i);\n      return { nickname: nick, user_id: userIdMatch?.[1] || '' };\n    })()\n  `);\n  let decodedTracknick = '';\n  try {\n    decodedTracknick = JSON.parse('\"' + tracknick.replace(/\\\\/g, '\\\\\\\\') + '\"');\n  } catch {\n    decodedTracknick = tracknick;\n  }\n  const nickname = domInfo.nickname || decodedTracknick;\n  if (!domInfo.user_id) {\n    throw new CommandExecutionError('Taobao my_itaobao rendered but no user_id extractable — stale cookie2 or layout drift');","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/taobao/auth.js#L4-L40","documentation":"verifyTaobaoIdentity navigates to the Taobao my_itaobao page and requires the 'tracknick' cookie to confirm an authenticated session. If page.getCookies() for https://www.taobao.com contains no tracknick cookie, the library throws AuthRequiredError because the session is not (or no longer) logged in. This is a deliberate signal that the caller must re-authenticate.","triggerScenarios":"Calling verifyTaobaoIdentity (or the auth poll flow) after page.goto on the my_itaobao URL when getCookies({url:'https://www.taobao.com'}) returns no cookie named 'tracknick'. Also triggered when the login redirect check passed but the session cookie was never set (bot detection, fresh browser context).","commonSituations":"Expired or cleared Taobao session; running in a fresh browser profile with no prior login; Taobao login blocked by anti-bot verification (slider captcha) so cookies never land; cookie domain scoping so tracknick isn't visible for www.taobao.com.","solutions":["Run the interactive login flow (loginUrl https://login.taobao.com/member/login.jhtml) and complete it before verifying","Persist and restore cookies/storage state from a previously successful login so tracknick exists on startup","Wait and retry the poll: the poll() callback intentionally throws this until hasTaobaoSessionCookie passes, so loop until user logs in","Check that the browser context is the same one used for login (no incognito/isolated context wipe)","Manually log into taobao.com in the controlled browser and confirm tracknick exists in devtools cookies"],"exampleFix":"// before\nawait verifyTaobaoIdentity(page); // throws if not logged in\n// after\nif (!(await hasTaobaoSessionCookie(page))) {\n  await interactiveLogin(page, 'https://login.taobao.com/member/login.jhtml');\n}\nawait verifyTaobaoIdentity(page);","handlingStrategy":"try-catch","validationCode":"const cookies = await page.getCookies({ url: 'https://www.taobao.com' });\nconst hasTracknick = cookies.some(c => c.name === 'tracknick');\nif (!hasTracknick) throw new Error('Run taobao login first');","typeGuard":"function isAuthed(cookies) {\n  return Array.isArray(cookies) && cookies.some(c => c.name === 'tracknick' && c.value);\n}","tryCatchPattern":"try {\n  const id = await verifyTaobaoIdentity(page);\n} catch (e) {\n  if (e instanceof AuthRequiredError) {\n    await runTaobaoLogin(page); // interactive login via login.jhtml\n    return verifyTaobaoIdentity(page);\n  }\n  throw e;\n}","preventionTips":["Persist cookies/storage state after each successful login and restore on startup","Call hasTaobaoSessionCookie before any authenticated scrape","Keep the login browser context alive; avoid recreating contexts mid-session","Watch for login.taobao.com redirects and treat them as re-login signals"],"tags":["auth","cookies","taobao","session-expired"],"backgroundTag":"auth-session-cookie-missing","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}