{"record":{"id":"d8034cde4b71e446","repo":"jackwener/OpenCLI","slug":"claude-session-incomplete-ajs-user-id-cookie-mis","errorCode":null,"errorMessage":"Claude session incomplete — ajs_user_id cookie missing","messagePattern":"Claude session incomplete — ajs_user_id cookie missing","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/claude/auth.js","lineNumber":38,"sourceCode":"      }\n      if (!res.ok) return { kind: 'http', httpStatus: res.status };\n      const d = await res.json();\n      if (!Array.isArray(d) || d.length === 0) {\n        return { kind: 'auth', detail: 'Claude /api/organizations empty' };\n      }\n      const userIdCookie = (document.cookie.split('; ').find(c => c.startsWith('ajs_user_id=')) || '').split('=')[1] || '';\n      const activeOrgCookie = (document.cookie.split('; ').find(c => c.startsWith('lastActiveOrg=')) || '').split('=')[1] || '';\n      const activeOrg = d.find(o => o.uuid === activeOrgCookie) || d[0];\n      return { ok: true, user_id: userIdCookie, org_name: activeOrg.name || '', org_uuid: activeOrg.uuid || '' };\n    } catch (e) {\n      return { kind: 'exception', detail: String(e && e.message || e) };\n    }\n  })()`);\n  if (result?.kind === 'auth') throw new AuthRequiredError('claude.ai', result.detail);\n  if (result?.kind === 'http') throw new CommandExecutionError(`HTTP ${result.httpStatus} from /api/organizations`);\n  if (result?.kind === 'exception') throw new CommandExecutionError(`Claude whoami failed: ${result.detail}`);\n  if (!result?.ok) throw new CommandExecutionError(`Unexpected Claude probe: ${JSON.stringify(result)}`);\n  if (!result.user_id) throw new AuthRequiredError('claude.ai', 'Claude session incomplete — ajs_user_id cookie missing');\n  return { user_id: String(result.user_id), org_name: String(result.org_name), org_uuid: String(result.org_uuid) };\n}\n\nregisterSiteAuthCommands({\n  site: 'claude',\n  domain: 'claude.ai',\n  loginUrl: 'https://claude.ai/login',\n  columns: ['user_id', 'org_name', 'org_uuid'],\n  quickCheck: hasClaudeSessionCookie,\n  verify: verifyClaudeIdentity,\n  poll: async (page) => {\n    if (!await hasClaudeSessionCookie(page)) {\n      throw new AuthRequiredError('claude.ai', 'Waiting for Claude sessionKey cookie');\n    }\n    return verifyClaudeIdentity(page);\n  },\n});\n","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/claude/auth.js#L20-L56","documentation":"This AuthRequiredError means the /api/organizations probe succeeded and returned org data, but the analytics cookie ajs_user_id was absent, so the library cannot report a user_id. The sessionKey cookie exists and the API accepts it, but the identity cookie Claude normally sets is missing — a partial or degraded login state.","triggerScenarios":"verifyClaudeIdentity returns ok from /api/organizations but document.cookie contains no ajs_user_id entry — e.g. login completed only partially, cookies were partially cleared, or Claude stopped setting the ajs_user_id cookie in a frontend update; also possible when third-party/cookie settings or a cookie-clearing extension strips analytics cookies.","commonSituations":"User cleared cookies selectively (kept sessionKey, removed analytics cookies); browser configured to block tracking/analytics cookies; privacy extensions (uBlock, cookie auto-delete) removing ajs_* cookies; Claude changing cookie naming in a new frontend release, breaking the library's expectation.","solutions":["Log out of claude.ai completely and log back in so all cookies (including ajs_user_id) are set fresh","Disable cookie-clearing/privacy extensions or whitelist claude.ai so analytics cookies persist","Allow cookies for claude.ai in browser settings (do not block third-party/analytics cookies for the domain)","If Claude removed/renamed the cookie, update the library to a version matching the current claude.ai behavior","Verify with an `opencli claude auth` re-run, which re-executes the login + verification flow"],"exampleFix":"// before\n// sessionKey present, ajs_user_id deleted by extension -> AuthRequiredError\n// after\n// browser extension: add claude.ai to cookie whitelist, then\nopencli claude auth && opencli claude whoami","handlingStrategy":"validation","validationCode":"const cookies = await page.getCookies({ url: 'https://claude.ai' });\nconst hasSession = cookies.some(c => c.name === 'sessionKey' && c.value);\nconst hasUserId = cookies.some(c => c.name === 'ajs_user_id' && c.value);\nif (!hasSession || !hasUserId) throw new Error('Incomplete claude.ai cookies — re-run `opencli claude auth`');","typeGuard":"function hasCompleteClaudeCookies(cookies) {\n  const names = new Set(cookies.filter(c => c.value).map(c => c.name));\n  return names.has('sessionKey') && names.has('ajs_user_id');\n}","tryCatchPattern":"try {\n  const identity = await verifyClaudeIdentity(page);\n} catch (e) {\n  if (e.message.includes('ajs_user_id cookie missing')) {\n    // partial session: full logout + fresh login restores all cookies\n    return runClaudeAuthFlow();\n  }\n  throw e;\n}","preventionTips":["Whitelist claude.ai in cookie-clearing/privacy extensions","Allow all cookies for claude.ai in browser settings","Always use the library's auth flow instead of copying cookies manually","Update the library if Claude renames its identity cookies"],"tags":["auth","cookies","claude","session"],"backgroundTag":"session-cookie-missing","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}