{"record":{"id":"7cd817fe0fd2080c","repo":"jackwener/OpenCLI","slug":"zhihu-api-v4-me-returned-http-status-anonymo","errorCode":null,"errorMessage":"Zhihu /api/v4/me returned HTTP ${status} — anonymous","messagePattern":"Zhihu /api/v4/me returned HTTP (.+?) — anonymous","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/zhihu/auth.js","lineNumber":32,"sourceCode":"  await page.wait(2);\n  const data = await page.evaluate(`\n    (async () => {\n      try {\n        const r = await fetch('https://www.zhihu.com/api/v4/me?include=url_token', { credentials: 'include' });\n        if (!r.ok) return { __httpError: r.status };\n        return await r.json();\n      } catch (e) {\n        return { __exception: String(e && e.message || e) };\n      }\n    })()\n  `);\n  if (data?.__exception) {\n    throw new CommandExecutionError(`Zhihu whoami failed: ${data.__exception}`);\n  }\n  if (!data || data.__httpError) {\n    const status = data?.__httpError;\n    if (status === 401 || status === 403) {\n      throw new AuthRequiredError('www.zhihu.com', `Zhihu /api/v4/me returned HTTP ${status} — anonymous`);\n    }\n    throw new CommandExecutionError(`Zhihu identity probe failed (HTTP ${status ?? 'unknown'})`);\n  }\n  if (!data.url_token) {\n    throw new AuthRequiredError('www.zhihu.com', 'Zhihu /api/v4/me returned no url_token — anonymous session');\n  }\n  return {\n    url_token: String(data.url_token),\n    name: String(data.name ?? ''),\n    uid: String(data.uid ?? data.id ?? ''),\n  };\n}\n\nregisterSiteAuthCommands({\n  site: 'zhihu',\n  domain: 'www.zhihu.com',\n  loginUrl: 'https://www.zhihu.com/signin',\n  columns: ['url_token', 'name', 'uid'],","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/zhihu/auth.js#L14-L50","documentation":"After the whoami script runs, if the response carries __httpError with status 401 or 403, the library concludes the session is anonymous and throws AuthRequiredError. Zhihu's /api/v4/me rejects unauthenticated requests with these statuses, so this is an authentication failure, not a code bug.","triggerScenarios":"A z_c0 cookie exists (so the earlier cookie check passed) but it is expired/invalid, so /api/v4/me returns HTTP 401 or 403 during verifyZhihuIdentity.","commonSituations":"Stale z_c0 cookie after Zhihu invalidated the session (password change, session revocation, long inactivity); copying a cookie from another browser that has since expired; logged out on another device invalidating the token.","solutions":["Re-login: run `opencli zhihu login` and complete sign-in to obtain a fresh z_c0 cookie.","Clear old cookies in the automation profile before re-login to avoid reusing the stale token.","If sessions keep dying, check whether something logs you out (shared profile used concurrently by multiple automation runs).","Catch AuthRequiredError and route the user to the login flow."],"exampleFix":"// before\nawait runZhihuCommand(); // AuthRequiredError: /api/v4/me returned HTTP 401 — anonymous\n// after\nif (!(await isZhihuLoggedIn(page))) {\n  await zhihuLogin(); // refresh z_c0\n}\nawait runZhihuCommand();","handlingStrategy":"try-catch","validationCode":"const cookies = await page.getCookies({ url: 'https://www.zhihu.com' });\nif (!cookies.some(c => c.name === 'z_c0' && c.value)) await runZhihuLogin(); // refresh possibly-stale cookie proactively","typeGuard":"function isAuthError(e) { return /HTTP (401|403)/.test(String(e.message)); }","tryCatchPattern":"try { const me = await verifyZhihuIdentity(page); } catch (e) { if (/HTTP (401|403)/.test(e.message)) { await zhihuLogin(); return verifyZhihuIdentity(page); } throw e; }","preventionTips":["Periodically re-login to refresh z_c0 before long-running jobs","Don't share one browser profile across concurrent automation runs","Catch 401/403 and trigger re-auth automatically","Monitor for logout events (password changes, device limits) that invalidate sessions"],"tags":["authentication","zhihu","http-401","http-403","session-expired"],"backgroundTag":"auth-cookie-expired","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}