{"record":{"id":"b40e161c7d19ef00","repo":"mastra-ai/mastra","slug":"failed-to-delete-session-res-status","errorCode":null,"errorMessage":"Failed to delete session (${res.status})","messagePattern":"Failed to delete session \\((.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory-ui/src/ui/domains/workspaces/services/user-sessions.ts","lineNumber":87,"sourceCode":"  );\n  return normalizeUserSession(result.session);\n}\n\nexport async function getUserSession(baseUrl: string, sessionId: string): Promise<FactoryUserSession> {\n  const res = await fetch(`${baseUrl}/web/user-sessions/${encodeURIComponent(sessionId)}`, {\n    headers: { Accept: 'application/json' },\n    credentials: 'include',\n  });\n  const body = await readJsonOrThrow<{ session: FactoryUserSessionPayload }>(res, 'Failed to load session');\n  return normalizeUserSession(body.session);\n}\n\nexport async function deleteUserSession(baseUrl: string, sessionId: string): Promise<void> {\n  const res = await fetch(`${baseUrl}/web/user-sessions/${encodeURIComponent(sessionId)}`, {\n    method: 'DELETE',\n    credentials: 'include',\n  });\n  if (!res.ok && res.status !== 404) throw new Error(`Failed to delete session (${res.status})`);\n}\n\n/** Ask the title model to re-name a session's conversation. Resolves to the new title. */\nexport async function regenerateSessionTitle(baseUrl: string, sessionId: string): Promise<string> {\n  const res = await fetch(`${baseUrl}/web/user-sessions/${encodeURIComponent(sessionId)}/title`, {\n    method: 'POST',\n    credentials: 'include',\n  });\n  const body: { title?: string; error?: string } = await res.json().catch(() => ({}));\n  if (!res.ok || !body.title) throw new Error(body.error ?? `Failed to rename session (${res.status})`);\n  return body.title;\n}\n","sourceCodeStart":69,"sourceCodeEnd":100,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory-ui/src/ui/domains/workspaces/services/user-sessions.ts#L69-L100","documentation":"deleteUserSession in mastracode/factory-ui/src/ui/domains/workspaces/services/user-sessions.ts throws this when the DELETE to `${baseUrl}/web/user-sessions/${sessionId}` returns a non-OK status other than 404. 404 is deliberately treated as success (session already gone, idempotent delete); any other failure — 401/403 auth, 500 server error, or a network-level non-JSON response — becomes this error.","triggerScenarios":"DELETE returns 401 (session cookie invalid), 403 (not the owner of the session), 405/409 (route changed or session is locked/active and server refuses deletion), 500, or 502 from a proxy. Only res.status === 404 is suppressed.","commonSituations":"User clicks 'log out device' in useDeleteWorkspaceMutation after the auth cookie expired; a server deploy changed the user-sessions route; a load balancer returns 502 during backend rollout; attempting to delete the session the request itself is authenticated with and the server rejects it with 409.","solutions":["Read the status code in the message; for 401/403 re-authenticate before retrying the delete.","Confirm sessionId is a valid session belonging to the current user via the sessions list endpoint.","Retry on 5xx/502/503 — deletes are idempotent here (404 tolerated), so a simple retry is safe.","If it persists, check the backend route still exists at /web/user-sessions/:id with method DELETE."],"exampleFix":"// before: any non-404 failure aborts with a generic message\nif (!res.ok && res.status !== 404) throw new Error(`Failed to delete session (${res.status})`);\n// after: tolerate 404 and transient 5xx with one retry\nif (!res.ok && res.status !== 404) {\n  if (res.status >= 500) await fetch(url, { method: 'DELETE', credentials: 'include' });\n  else throw new Error(`Failed to delete session (${res.status})`);\n}","handlingStrategy":"try-catch","validationCode":"const sessions = await fetchUserSessions(baseUrl);\nif (!sessions.some(s => s.id === sessionId)) return; // already gone — skip the DELETE","typeGuard":"function isSessionId(v: unknown): v is string {\n  return typeof v === 'string' && v.length > 0;\n}","tryCatchPattern":"try {\n  await deleteUserSession(baseUrl, sessionId);\n} catch (err) {\n  const status = Number((err as Error).message.match(/\\((\\d{3})\\)/)?.[1] ?? 0);\n  if (status >= 500) await deleteUserSession(baseUrl, sessionId); // idempotent: 404 tolerated\n  else if (status === 401 || status === 403) await reauthAndRetry();\n  else toast.error('Could not remove session');\n}","preventionTips":["Treat delete as idempotent — the API already ignores 404, so retry 5xx freely.","Check the session belongs to the current user before calling delete.","Renew auth before batch-removing sessions so one expired cookie doesn't fail the batch."],"tags":["http","fetch","delete","network"],"backgroundTag":"http-request-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}