{"record":{"id":"9ca2f9c8286b6f63","repo":"jackwener/OpenCLI","slug":"unexpected-linux-do-probe-json-stringify-probe","errorCode":null,"errorMessage":"Unexpected Linux.do probe: ${JSON.stringify(probe)}","messagePattern":"Unexpected Linux\\.do probe: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/linux-do/auth.js","lineNumber":38,"sourceCode":"        credentials: 'include',\n        headers: { Accept: 'application/json' },\n      });\n      if (r.status === 401 || r.status === 403) {\n        return { kind: 'auth', detail: 'Linux.do /u/<self>.json HTTP ' + r.status };\n      }\n      if (!r.ok) return { kind: 'http', httpStatus: r.status };\n      const d = await r.json();\n      const user = d?.user;\n      if (!user || !user.id) return { kind: 'auth', detail: 'Linux.do /u/<self>.json missing user.id' };\n      return { ok: true, user_id: String(user.id), username: String(user.username || u), name: String(user.name || '') };\n    } catch (e) {\n      return { kind: 'exception', detail: String(e && e.message || e) };\n    }\n  })()`);\n  if (probe?.kind === 'auth') throw new AuthRequiredError('linux.do', probe.detail);\n  if (probe?.kind === 'http') throw new CommandExecutionError(`HTTP ${probe.httpStatus} from Linux.do /u/<self>.json`);\n  if (probe?.kind === 'exception') throw new CommandExecutionError(`Linux.do whoami failed: ${probe.detail}`);\n  if (!probe?.ok) throw new CommandExecutionError(`Unexpected Linux.do probe: ${JSON.stringify(probe)}`);\n  return { user_id: probe.user_id, username: probe.username, name: probe.name };\n}\n\nregisterSiteAuthCommands({\n  site: 'linux-do',\n  domain: 'linux.do',\n  loginUrl: 'https://linux.do/login',\n  columns: ['user_id', 'username', 'name'],\n  quickCheck: hasLinuxDoSessionCookie,\n  verify: verifyLinuxDoIdentity,\n  poll: async (page) => {\n    if (!await hasLinuxDoSessionCookie(page)) {\n      throw new AuthRequiredError('linux.do', 'Waiting for Linux.do _t cookie');\n    }\n    return verifyLinuxDoIdentity(page);\n  },\n});\n","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linux-do/auth.js#L20-L56","documentation":"verifyLinuxDoIdentity probes the signed-in linux.do session by evaluating a fetch of /u/<self>.json in the browser page and classifying the result by `kind`. Auth, HTTP, and exception outcomes have dedicated error branches; this final fallback CommandExecutionError fires only when the probe resolves to an unrecognized shape — i.e. `probe` is null/undefined, or an object without `ok: true` and without any known `kind`. The library throws it because a structurally unexpected probe result means the page environment (evaluate serialization, site JS) behaved in an unanticipated way.","triggerScenarios":"1) `page.evaluate` returns null/undefined (page navigated away mid-evaluate, context destroyed, or evaluate serialization failure) so `probe?.ok` and `probe?.kind` are both falsy. 2) The in-page IIFE is modified/monkey-patched or the browser blocks `fetch` in a way that neither throws nor returns a known kind. 3) A linux.do site change makes the probe object shape drift from {kind|ok}. Since the IIFE always returns a tagged object, in practice this is almost always probe === null/undefined from a broken evaluate context.","commonSituations":"Browser automation page crashed or was closed during login polling; the linux.do tab navigated (e.g. redirect during page.goto + page.wait(2)) before evaluate returned; running against a mocked/fake page object in tests that doesn't return the expected tagged probe; older browser or extension interfering with fetch inside evaluate.","solutions":["Close and relaunch the browser session, then retry `opencli linux-do login`/verify — a transient page-context crash is the most common cause of a null probe.","Ensure no navigation runs concurrently with verification; verify only after page.goto('https://linux.do/') + page.wait(2) completes (already done by verifyLinuxDoIdentity — remove custom callers that navigate during poll).","Check the JSON payload in the message: it shows the actual probe; if it's an object with an unknown kind, update the CLI or site probe to the current linux.do behavior.","Re-run with a fresh browser profile to rule out extensions or cached service workers interfering with in-page fetch."],"exampleFix":"// before (custom poller navigating during verify)\nawait page.goto('https://linux.do/latest');\nconst identity = await verifyLinuxDoIdentity(page);\n// after (let verifyLinuxDoIdentity own navigation)\nawait page.waitForLoadState('networkidle');\nconst identity = await verifyLinuxDoIdentity(page);","handlingStrategy":"try-catch","validationCode":"// before verifying, confirm the page and session are usable\nif (!page) throw new Error('Browser page required before linux.do verify');\nconst cookies = await page.getCookies({ url: 'https://linux.do' });\nif (!cookies.some(c => c.name === '_t' && c.value)) {\n  throw new Error('Not signed in to linux.do: _t cookie missing');\n}","typeGuard":"function isKnownProbe(p) {\n  return !!p && typeof p === 'object' &&\n    (p.ok === true || ['auth', 'http', 'exception'].includes(p.kind));\n}","tryCatchPattern":"try {\n  const identity = await verifyLinuxDoIdentity(page);\n} catch (err) {\n  if (/Unexpected Linux\\.do probe/.test(err.message)) {\n    // probe came back null/unrecognized: reopen the page and retry once\n    page = await browser.newPage();\n    await page.goto('https://linux.do');\n    return verifyLinuxDoIdentity(page);\n  }\n  if (err instanceof AuthRequiredError) return promptLogin();\n  throw err;\n}","preventionTips":["Never navigate the page concurrently while verifyLinuxDoIdentity is polling/evaluating.","Always confirm the linux.do _t cookie exists before invoking verify to avoid probing dead sessions.","Reuse the CLI's own login/verify entry points instead of wrapping verify with custom navigation.","Retry once with a fresh page when you see an 'Unexpected Linux.do probe' — it is usually a transient context loss.","Pin/update browser automation runtimes together; serialization changes can turn valid probes into null."],"tags":["linux-do","authentication","browser-automation","unexpected-state"],"backgroundTag":"browser-probe-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}