{"record":{"id":"775631f40d762c9a","repo":"jackwener/OpenCLI","slug":"auth-775631","errorCode":null,"errorMessage":"auth","messagePattern":"auth","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/rednote/auth.js","lineNumber":34,"sourceCode":"    (() => {\n      const state = window.__INITIAL_STATE__;\n      if (!state?.user) {\n        return { kind: 'auth', detail: 'Rednote __INITIAL_STATE__.user missing' };\n      }\n      const loggedIn = state.user.loggedIn?._value;\n      const userInfo = state.user.userInfo?._value || {};\n      if (loggedIn !== true) {\n        return { kind: 'auth', detail: 'Rednote loggedIn._value=' + String(loggedIn) + ' — anonymous' };\n      }\n      const userId = String(userInfo.userId || userInfo.user_id || '');\n      const nickname = String(userInfo.nickname || userInfo.name || '');\n      if (!userId) {\n        return { kind: 'auth', detail: 'Rednote logged-in but userId missing — stale session' };\n      }\n      return { ok: true, user_id: userId, nickname };\n    })()\n  `);\n  if (probe?.kind === 'auth') throw new AuthRequiredError('rednote.com', probe.detail);\n  if (!probe?.ok) throw new CommandExecutionError(`Unexpected Rednote probe: ${JSON.stringify(probe)}`);\n  return { user_id: probe.user_id, nickname: probe.nickname };\n}\n\nregisterSiteAuthCommands({\n  site: 'rednote',\n  domain: 'rednote.com',\n  loginUrl: 'https://www.rednote.com/explore',\n  columns: ['user_id', 'nickname'],\n  quickCheck: hasRednoteSessionCookie,\n  verify: verifyRednoteIdentity,\n  poll: async (page) => {\n    if (!await hasRednoteSessionCookie(page)) {\n      throw new AuthRequiredError('rednote.com', 'Waiting for Rednote web_session cookie');\n    }\n    return verifyRednoteIdentity(page);\n  },\n});","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/rednote/auth.js#L16-L52","documentation":"This AuthRequiredError is thrown by verifyRednoteIdentity when the in-page probe reports kind === 'auth' with detail 'Rednote logged-in but userId missing — stale session'. Unlike error 3403, a web_session cookie exists, but the page's __INITIAL_STATE__ has no userId, meaning the session cookie is invalid/expired server-side. The library signals that re-authentication is required even though the browser appears logged in.","triggerScenarios":"Calling a rednote command after verifyRednoteIdentity passes the cookie check but the evaluate() probe on https://www.rednote.com/explore returns { kind: 'auth', detail: 'Rednote logged-in but userId missing — stale session' } — i.e., web_session cookie present but rejected or unrecognized by the server.","commonSituations":"Server-side session expiry while the cookie lingers in the browser; rednote rotating/invalding session tokens (e.g., after password change or remote logout); copying a stale cookie into an automation profile; site renaming __INITIAL_STATE__ fields so userId extraction fails and looks like a stale session.","solutions":["Re-run the rednote login flow to mint a fresh web_session cookie, then retry the command.","Clear the old web_session cookie before logging in again so the stale value can't be reused.","If sessions keep dying quickly, check that the automation browser isn't sharing the profile with a live manual session that logs it out.","Confirm the probe's extraction (window.__INITIAL_STATE__ userId path) still matches the current rednote.com page; update if the site changed.","Catch AuthRequiredError and automate the re-login path instead of surfacing the error to end users."],"exampleFix":"// before: assuming cookie presence means valid session\nif (await hasRednoteSessionCookie(page)) return;\n\n// after: handle stale-session auth errors by re-authenticating\ntry {\n  await rednoteCommand(page);\n} catch (e) {\n  if (e instanceof AuthRequiredError) {\n    await page.deleteCookies({ name: 'web_session', url: 'https://www.rednote.com' });\n    await rednoteLogin(page);\n    await rednoteCommand(page);\n  } else throw e;\n}","handlingStrategy":"try-catch","validationCode":"const probe = await page.evaluate(`(() => {\n  const userId = window.__INITIAL_STATE__?.user?.userId;\n  return { hasCookieSession: !!document.cookie.match(/web_session=/), userId };\n})()`);\nif (probe.hasCookieSession && !probe.userId) {\n  await rednoteLogin(page); // cookie exists but session is stale\n}","typeGuard":"function hasValidRednoteSession(probe) {\n  return !!probe && probe.kind === 'ok' && typeof probe.user_id === 'string' && probe.user_id.length > 0;\n}","tryCatchPattern":"try {\n  await rednoteCommand(page);\n} catch (e) {\n  if (e instanceof AuthRequiredError && /stale session/i.test(e.message)) {\n    await page.deleteCookies({ name: 'web_session', url: 'https://www.rednote.com' });\n    await rednoteLogin(page);\n    return rednoteCommand(page);\n  }\n  throw e;\n}","preventionTips":["Treat cookie presence as necessary but not sufficient — verify a page-level identity probe too.","Delete the old web_session cookie before re-login so stale values can't be reused.","Refresh sessions proactively if they expire quickly rather than waiting for commands to fail.","Don't share one browser profile between a live manual session and automation (remote logout invalidates the cookie)."],"tags":["auth","stale-session","rednote","session-expired"],"backgroundTag":"stale-session-cookie","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}