{"record":{"id":"f85bbe67ca9b9329","repo":"upstash/context7","slug":"failed-to-fetch-user-info","errorCode":null,"errorMessage":"Failed to fetch user info","messagePattern":"Failed to fetch user info","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/auth.ts","lineNumber":262,"sourceCode":"  }\n}\n\ninterface WhoamiResponse {\n  success: boolean;\n  name: string | null;\n  email: string | null;\n  teamspace: { id: string; name: string } | null;\n}\n\nasync function fetchWhoami(accessToken: string): Promise<WhoamiResponse> {\n  const response = await fetch(`${getBaseUrl()}/api/dashboard/whoami`, {\n    headers: {\n      Authorization: `Bearer ${accessToken}`,\n    },\n  });\n\n  if (!response.ok) {\n    throw new Error(\"Failed to fetch user info\");\n  }\n\n  return (await response.json()) as WhoamiResponse;\n}\n","sourceCodeStart":244,"sourceCodeEnd":267,"githubUrl":"https://github.com/upstash/context7/blob/ca15df0443ee770506fc4eb270d1efc71d483933/packages/cli/src/commands/auth.ts#L244-L267","documentation":"Thrown by fetchWhoami() in the CLI auth command when the GET to /api/dashboard/whoami returns a non-2xx status. The CLI sends the stored access token as a Bearer header to verify the session and load the user's teamspace; any failure here aborts that lookup. The thrown Error carries no status code, so the original HTTP status is lost by the time it reaches a caller.","triggerScenarios":"A whoami request returns 401 (access token expired or revoked), 403 (token valid but not authorized for dashboard), 404/000 (getBaseUrl() points at the wrong host so the path does not resolve), or any 5xx from the dashboard backend. Note: a low-level network failure (DNS, TLS) is NOT caught here — fetch() rejects first and a different error propagates.","commonSituations":"Long-running CLI session whose access token expired since login; user pointed the CLI at a stale/wrong base URL; dashboard backend temporarily down during a deploy; token revoked from another device.","solutions":["Re-run `auth login` (or the CLI's refresh command) to mint a fresh access token, then retry.","Verify getBaseUrl() resolves to the correct dashboard host (check the configured base URL / env override).","If the caller needs the real cause, reproduce the request with curl using the same Bearer token to read the actual status code and body.","For transient 5xx, retry the whoami call after a short delay rather than forcing a full re-login."],"exampleFix":"// before\nif (!response.ok) {\n  throw new Error(\"Failed to fetch user info\");\n}\n\n// after — preserve status so callers can branch on 401 vs 5xx\nif (!response.ok) {\n  const detail = await response.text().catch(() => \"\");\n  const err = new Error(`Failed to fetch user info (HTTP ${response.status})`);\n  (err as any).status = response.status;\n  (err as any).body = detail.slice(0, 200);\n  throw err;\n}","handlingStrategy":"try-catch","validationCode":"// Validate the token shape before calling fetchWhoami.\nfunction hasUsableToken(token: unknown): token is string {\n  return typeof token === \"string\" && token.length > 0 && token.split(\".\").length >= 2;\n}\nif (!hasUsableToken(accessToken)) {\n  throw new Error(\"No usable access token — run `auth login` first.\");\n}\nconst me = await fetchWhoami(accessToken);","typeGuard":"function isWhoamiResponse(v: unknown): v is WhoamiResponse {\n  return (\n    typeof v === \"object\" && v !== null &&\n    typeof (v as any).success === \"boolean\"\n  );\n}","tryCatchPattern":"try {\n  const me = await fetchWhoami(accessToken);\n} catch (e) {\n  // fetchWhoami erases the status; treat any failure as \"session invalid\"\n  // and prompt re-login rather than looping.\n  await reauthenticate();\n  return;\n}","preventionTips":["Refresh the access token proactively before its expiry rather than waiting for whoami to fail.","Wrap whoami in a single retry for transient 5xx before forcing re-login.","Patch fetchWhoami to attach response.status to the error so callers can distinguish 401 from 5xx."],"tags":["auth","http","cli","whoami"],"backgroundTag":null,"analyzedSha":"ca15df0443ee770506fc4eb270d1efc71d483933","analyzedAt":"2026-08-12T13:31:48.440Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}