{"record":{"id":"8d06eda0be655b2d","repo":"jackwener/OpenCLI","slug":"unexpected-rednote-probe-json-stringify-probe","errorCode":null,"errorMessage":"Unexpected Rednote probe: ${JSON.stringify(probe)}","messagePattern":"Unexpected Rednote probe: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/rednote/auth.js","lineNumber":35,"sourceCode":"      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});\n","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/rednote/auth.js#L17-L53","documentation":"verifyRednoteIdentity runs an in-page probe against window.__INITIAL_STATE__ to confirm the Rednote session. The probe classifies every failure it can recognize as kind:'auth' (thrown as AuthRequiredError) or returns ok:true on success. If the probe returns anything else — null/undefined (evaluate failed), an unexpected shape, or a malformed object — the code throws CommandExecutionError with the JSON of the probe so the unrecognized state is visible.","triggerScenarios":"The page.evaluate call returns null (script error, navigation interrupted mid-evaluate, page clobbered), or returns an object that is neither {kind:'auth'} nor {ok:true} — e.g. Rednote changed its state shape so probe returns {kind:'other'} or truthy garbage, or the browser context was destroyed and evaluate resolved to undefined/null while the web_session cookie still existed.","commonSituations":"Rednote frontend redeploy changing __INITIAL_STATE__ structure so the IIFE's return paths no longer match; flaky automation runs where the page navigates/reloads between goto and evaluate; anti-bot interstitials replacing the page content; stale automation sessions where evaluate throws internally and the wrapper swallows it, returning null.","solutions":["Re-run the command once — transient page navigation or a mid-evaluate reload commonly produces a null probe.","Log in again via the site's auth flow so the probe sees a fresh, valid __INITIAL_STATE__ (if the state is stale, the probe usually reports kind:'auth' instead, but refresh anyway).","Inspect the JSON in the message: probe:null means evaluate failed (page context gone); an odd object means the state shape changed.","Check for a Rednote frontend update and update this probe script (clis/rednote/auth.js) to match the new __INITIAL_STATE__ shape.","Use a non-headless or less-flagged browser session if anti-bot interstitials are replacing the page before evaluate runs."],"exampleFix":"// before (probe returns null on transient navigation)\nif (!probe?.ok) throw new CommandExecutionError(`Unexpected Rednote probe: ${JSON.stringify(probe)}`);\n// after (retry once before failing)\nif (!probe?.ok) {\n  await page.wait(2);\n  probe = await page.evaluate(probeScript);\n}\nif (!probe?.ok) throw new CommandExecutionError(`Unexpected Rednote probe: ${JSON.stringify(probe)}`);","handlingStrategy":"try-catch","validationCode":"// before calling, ensure a session cookie exists so the probe path is even reachable\nconst cookies = await page.getCookies({ url: 'https://www.rednote.com' });\nif (!cookies.some(c => c.name === 'web_session' && c.value)) {\n  throw new Error('No rednote web_session cookie — run the rednote auth flow first');\n}","typeGuard":"function isProbeOk(p) {\n  return typeof p === 'object' && p !== null && p.ok === true\n    && typeof p.user_id === 'string' && p.user_id.length > 0;\n}","tryCatchPattern":"try {\n  const identity = await verifyRednoteIdentity(page);\n} catch (err) {\n  if (err instanceof AuthRequiredError) {\n    // re-auth flow\n  } else if (err instanceof CommandExecutionError) {\n    // transient probe failure: wait and retry once, then surface err.message (contains probe JSON)\n    await page.wait(3);\n    return retryVerify(page);\n  }\n  throw err;\n}","preventionTips":["Always complete the rednote auth login before calling commands that verify identity.","Retry once on CommandExecutionError — transient page reloads commonly null the probe.","Keep browser automation flags minimal so anti-bot interstitials don't replace the page.","Track Rednote frontend changes; the probe depends on window.__INITIAL_STATE__ shape.","Check the probe JSON in the error message to distinguish null (evaluate failed) from odd shapes (state changed)."],"tags":["command-execution","browser-automation","rednote","unexpected-state"],"backgroundTag":"unexpected-page-state","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}