{"record":{"id":"e58536eb9a3a1fd9","repo":"jackwener/OpenCLI","slug":"unexpected-jianyu-probe-json-stringify-probe","errorCode":null,"errorMessage":"Unexpected Jianyu probe: ${JSON.stringify(probe)}","messagePattern":"Unexpected Jianyu probe: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/jianyu/auth.js","lineNumber":45,"sourceCode":"        try {\n          const u = JSON.parse(userScript);\n          userId = userId || String(u.id || u.userId || '');\n          name = String(u.name || u.realName || u.nickName || '');\n        } catch {}\n      }\n      const cookieUid = (document.cookie.split('; ').find(c => c.startsWith('userid_secure=')) || '').split('=')[1] || '';\n      userId = userId || cookieUid;\n      if (!userId && !name) {\n        return { kind: 'auth', detail: 'Jianyu protected page 200 but no user identity surface' };\n      }\n      return { ok: true, user_id: userId, name };\n    } catch (e) {\n      return { kind: 'exception', detail: String(e && e.message || e) };\n    }\n  })()`);\n  if (probe?.kind === 'auth') throw new AuthRequiredError('jianyu360.cn', probe.detail);\n  if (probe?.kind === 'exception') throw new CommandExecutionError(`Jianyu whoami failed: ${probe.detail}`);\n  if (!probe?.ok) throw new CommandExecutionError(`Unexpected Jianyu probe: ${JSON.stringify(probe)}`);\n  return { user_id: probe.user_id, name: probe.name };\n}\n\nregisterSiteAuthCommands({\n  site: 'jianyu',\n  domain: 'jianyu360.cn',\n  loginUrl: 'https://www.jianyu360.cn/',\n  columns: ['user_id', 'name'],\n  quickCheck: hasJianyuUserCookie,\n  verify: verifyJianyuIdentity,\n  poll: async (page) => {\n    if (!await hasJianyuUserCookie(page)) {\n      throw new AuthRequiredError('jianyu360.cn', 'Waiting for Jianyu userid_secure cookie');\n    }\n    return verifyJianyuIdentity(page);\n  },\n});\n","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/jianyu/auth.js#L27-L63","documentation":"CommandExecutionError thrown by verifyJianyuIdentity when the probe returns a result that is neither kind:'auth', kind:'exception', nor ok:true — i.e. an unrecognized probe shape. The message embeds the full JSON of the probe result for diagnosis. This guards against the probe contract drifting (e.g. a null/undefined probe if page.evaluate returned nothing, or a future probe variant returning new kinds).","triggerScenarios":"page.evaluate returns null/undefined because the async IIFE result was not serialized or the page navigated mid-evaluation; or the probe code was modified to return a new result shape without updating the kind dispatch in verifyJianyuIdentity.","commonSituations":"Upgrading or locally patching the probe script and forgetting to add a matching branch; page redirects during page.evaluate causing undefined return; browser automation layer returning undefined for async evaluations.","solutions":["Inspect the JSON in the error message to see the actual probe value returned","If probe is null/undefined, ensure the page stays on www.jianyu360.cn (no redirect) during evaluation and that page.evaluate awaits the async IIFE properly","If you customized the probe, update the dispatch in verifyJianyuIdentity to handle the new kind or return { ok: true, ... }","Re-run verify after fixing the evaluation harness; confirm quickCheck (userid_secure cookie) passes first"],"exampleFix":"// before: probe returns new shape { loggedIn: true, userId } without ok\nif (!probe?.ok) throw new CommandExecutionError(`Unexpected Jianyu probe: ${JSON.stringify(probe)}`);\n// after: normalize new shape\nif (probe?.loggedIn) return { user_id: probe.userId, name: probe.name || '' };\nif (!probe?.ok) throw new CommandExecutionError(`Unexpected Jianyu probe: ${JSON.stringify(probe)}`);","handlingStrategy":"validation","validationCode":"const probe = await page.evaluate(probeScript);\nif (probe == null || typeof probe !== 'object' || !('kind' in probe)) {\n  throw new Error('Probe returned no result — page likely navigated during evaluation');\n}","typeGuard":"function isKnownProbeResult(probe) {\n  return probe != null && typeof probe === 'object' &&\n    (probe.kind === 'auth' || probe.kind === 'exception' || probe.ok === true);\n}","tryCatchPattern":"try {\n  return await verifyJianyuIdentity(page);\n} catch (e) {\n  if (/Unexpected Jianyu probe: null/.test(e.message)) {\n    await page.goto('https://www.jianyu360.cn/'); // re-anchor and retry once\n    return verifyJianyuIdentity(page);\n  }\n  throw e;\n}","preventionTips":["Never navigate the page concurrently with the probe evaluation","If you modify the probe script, keep its return contract in sync with the dispatch branches","Log the embedded probe JSON in the message before discarding the error","Add a unit test asserting the probe result contract"],"tags":["contract-violation","probe","jianyu","selector-drift"],"backgroundTag":"unexpected-response-shape","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}