{"record":{"id":"5cca3ca1e747d0a2","repo":"jackwener/OpenCLI","slug":"unexpected-jike-identity-probe-json-stringify-p","errorCode":null,"errorMessage":"Unexpected Jike identity probe: ${JSON.stringify(probe)}","messagePattern":"Unexpected Jike identity probe: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/jike/utils.js","lineNumber":33,"sourceCode":"      headers: { 'x-jike-access-token': token, Accept: 'application/json' },\n    });\n    if (r.status === 401 || r.status === 403) return { kind: 'auth', detail: 'Jike users/profile HTTP ' + r.status };\n    if (!r.ok) return { kind: 'http', httpStatus: r.status };\n    const d = await r.json();\n    const u = d && d.user;\n    if (!u || !u.id) return { kind: 'auth', detail: 'Jike users/profile returned no user (anonymous)' };\n    return { ok: true, user_id: String(u.id), screen_name: String(u.screenName || ''), username: String(u.username || '') };\n  } catch (e) {\n    return { kind: 'exception', detail: String(e && e.message || e) };\n  }\n})()`;\n\nexport async function requireJikeIdentity(page) {\n  const probe = await page.evaluate(JIKE_IDENTITY_PROBE);\n  if (probe?.kind === 'auth') throw new AuthRequiredError('web.okjike.com', probe.detail);\n  if (probe?.kind === 'http') throw new CommandExecutionError(`HTTP ${probe.httpStatus} from Jike users/profile`);\n  if (probe?.kind === 'exception') throw new CommandExecutionError(`Jike identity probe failed: ${probe.detail}`);\n  if (!probe?.ok) throw new CommandExecutionError(`Unexpected Jike identity probe: ${JSON.stringify(probe)}`);\n  return { user_id: probe.user_id, screen_name: probe.screen_name, username: probe.username };\n}\n\nexport function normalizeJikeLimit(raw, defaultValue = 20) {\n  const limit = raw ?? defaultValue;\n  if (!Number.isInteger(limit) || limit < 1) {\n    throw new ArgumentError('--limit must be a positive integer');\n  }\n  return limit;\n}\n\nexport async function postJikeApi(page, path, requestBody, label) {\n  const url = `https://api.ruguoapp.com${path}`;\n  const outcome = await page.evaluate(`(async () => {\n    const token = localStorage.getItem('JK_ACCESS_TOKEN') || '';\n    const deviceId = localStorage.getItem('JK_DEVICE_ID') || '';\n    if (!token) return { kind: 'auth', detail: 'Jike access token is missing' };\n    const headers = {","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/jike/utils.js#L15-L51","documentation":"Defensive CommandExecutionError thrown by requireJikeIdentity when the probe result has no recognized 'kind' and probe.ok is falsy — i.e. page.evaluate returned something unexpected (null, undefined, or a malformed object). The probe is serialized into the message for diagnosis.","triggerScenarios":"Calling requireJikeIdentity when page.evaluate resolves to null (script aborted by navigation/close), returns undefined, or an object without the expected kind/ok fields due to a browser automation layer change.","commonSituations":"Browser tab closed or navigated during evaluate; Playwright/Puppeteer version mismatch altering evaluate serialization; a race where the command runs before the probe string executes.","solutions":["Retry the command — null results are often transient races","Ensure the page remains open and idle while the command executes","Check browser automation library versions match what the CLI expects","Report the serialized probe payload in an issue if it reproduces consistently"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const identity = await verifyJikeIdentity(page);\n} catch (e) {\n  if (String(e.message).startsWith('Unexpected Jike identity probe')) {\n    await sleep(1000);\n    return verifyJikeIdentity(page); // transient null/abort — retry\n  }\n  throw e;\n}","preventionTips":["Keep the page open and idle while identity verification runs","Retry once before treating it as a hard failure","Align browser automation library versions with the CLI","Include the serialized probe payload when reporting persistent issues"],"tags":["defensive","browser-automation","unexpected-payload"],"backgroundTag":"unexpected-response-shape","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}