{"record":{"id":"02f858c6a16adf65","repo":"jackwener/OpenCLI","slug":"unexpected-nowcoder-probe-json-stringify-probe","errorCode":null,"errorMessage":"Unexpected nowcoder probe: ${JSON.stringify(probe)}","messagePattern":"Unexpected nowcoder probe: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"warning","filePath":"clis/nowcoder/auth.js","lineNumber":49,"sourceCode":"      return { kind: 'auth', detail: 'nowcoder profile returned no user data (anonymous)' };\n    }\n    return { ok: true, user_id: String(d.data.id), nickname: String(d.data.nickname || '') };\n  } catch (e) {\n    return { kind: 'exception', detail: String(e && e.message || e) };\n  }\n})()`;\n\nasync function verifyNowcoderIdentity(page) {\n  if (!await hasNowcoderSessionCookie(page)) {\n    throw new AuthRequiredError('nowcoder.com', 'Nowcoder t cookie missing (anonymous)');\n  }\n  await page.goto('https://www.nowcoder.com/');\n  await page.wait(2);\n  const probe = await page.evaluate(WHOAMI_PROBE);\n  if (probe?.kind === 'auth') throw new AuthRequiredError('nowcoder.com', probe.detail);\n  if (probe?.kind === 'http') throw new CommandExecutionError(`HTTP ${probe.httpStatus} from nowcoder profile API`);\n  if (probe?.kind === 'exception') throw new CommandExecutionError(`Nowcoder whoami failed: ${probe.detail}`);\n  if (!probe?.ok) throw new CommandExecutionError(`Unexpected nowcoder probe: ${JSON.stringify(probe)}`);\n  return { user_id: probe.user_id, nickname: probe.nickname };\n}\n\nregisterSiteAuthCommands({\n  site: 'nowcoder',\n  domain: 'nowcoder.com',\n  loginUrl: 'https://www.nowcoder.com/login',\n  columns: ['user_id', 'nickname'],\n  verify: verifyNowcoderIdentity,\n  poll: async (page) => {\n    if (!await hasNowcoderSessionCookie(page)) {\n      throw new AuthRequiredError('nowcoder.com', 'Waiting for Nowcoder login');\n    }\n    return verifyNowcoderIdentity(page);\n  },\n});\n","sourceCodeStart":31,"sourceCodeEnd":66,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/nowcoder/auth.js#L31-L66","documentation":"After checking known probe kinds (auth/http/exception), verifyNowcoderIdentity throws CommandExecutionError 'Unexpected nowcoder probe: <json>' if the probe result is neither {ok:true} nor a recognized kind — e.g. null/undefined probe, a probe missing `ok`, or an unrecognized structure. This is a defensive catch-all indicating the probe contract changed or evaluate returned garbage.","triggerScenarios":"page.evaluate returning null (script failed to return), an older browser serializing differently, WHOAMI_PROBE edited so the success path lost {ok:true}, or navigation to an error page returning an unexpected object.","commonSituations":"Library version mismatch between probe script and verifier; headless browser quirks returning undefined from evaluate; DOM so broken the probe returned a shape the verifier doesn't know.","solutions":["Inspect the JSON in the message to see what the probe actually returned","Ensure page.evaluate is executing WHOAMI_PROBE (a fully loaded nowcoder.com page)","Sync WHOAMI_PROBE and verifyNowcoderIdentity so success always includes ok:true, user_id, nickname","Update library/browser if evaluate serialization behavior changed"],"exampleFix":"// before\nconst probe = await page.evaluate(WHOAMI_PROBE);\nif (probe?.kind === 'auth') throw new AuthRequiredError('nowcoder.com', probe.detail);\n// after\nconst probe = await page.evaluate(WHOAMI_PROBE);\nif (!probe || typeof probe !== 'object') {\n  throw new CommandExecutionError(`Unexpected nowcoder probe: ${JSON.stringify(probe)}`);\n}\nif (probe?.kind === 'auth') throw new AuthRequiredError('nowcoder.com', probe.detail);","handlingStrategy":"type-guard","validationCode":"const probe = await page.evaluate(WHOAMI_PROBE);\nif (!probe || typeof probe !== 'object') {\n  throw new CommandExecutionError(`Unexpected nowcoder probe: ${JSON.stringify(probe)}`);\n}","typeGuard":"function isValidProbe(p) {\n  return !!p && typeof p === 'object' &&\n    (p.ok === true || ['auth','http','exception'].includes(p.kind));\n}","tryCatchPattern":"try {\n  return await verifyNowcoderIdentity(page);\n} catch (e) {\n  if (/Unexpected nowcoder probe: null|undefined/.test(e.message)) {\n    // evaluate returned nothing — reload page and retry\n    await page.goto('https://www.nowcoder.com/');\n    return verifyNowcoderIdentity(page);\n  }\n  throw e;\n}","preventionTips":["Keep WHOAMI_PROBE and verifyNowcoderIdentity in the same version","Ensure the page is fully loaded before evaluate so the probe returns a real object","Assert on the probe shape in tests (ok/kind/user_id)","Log full JSON of unexpected probes to spot contract drift early"],"tags":["defensive-check","contract-mismatch","page-evaluate","nowcoder"],"backgroundTag":"unexpected-response-shape","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}