mastra-ai/mastra · error
Failed to delete session (${res.status})
Error message
Failed to delete session (${res.status}) What it means
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.
Source
Thrown at mastracode/factory-ui/src/ui/domains/workspaces/services/user-sessions.ts:87
);
return normalizeUserSession(result.session);
}
export async function getUserSession(baseUrl: string, sessionId: string): Promise<FactoryUserSession> {
const res = await fetch(`${baseUrl}/web/user-sessions/${encodeURIComponent(sessionId)}`, {
headers: { Accept: 'application/json' },
credentials: 'include',
});
const body = await readJsonOrThrow<{ session: FactoryUserSessionPayload }>(res, 'Failed to load session');
return normalizeUserSession(body.session);
}
export async function deleteUserSession(baseUrl: string, sessionId: string): Promise<void> {
const res = await fetch(`${baseUrl}/web/user-sessions/${encodeURIComponent(sessionId)}`, {
method: 'DELETE',
credentials: 'include',
});
if (!res.ok && res.status !== 404) throw new Error(`Failed to delete session (${res.status})`);
}
/** Ask the title model to re-name a session's conversation. Resolves to the new title. */
export async function regenerateSessionTitle(baseUrl: string, sessionId: string): Promise<string> {
const res = await fetch(`${baseUrl}/web/user-sessions/${encodeURIComponent(sessionId)}/title`, {
method: 'POST',
credentials: 'include',
});
const body: { title?: string; error?: string } = await res.json().catch(() => ({}));
if (!res.ok || !body.title) throw new Error(body.error ?? `Failed to rename session (${res.status})`);
return body.title;
}
View on GitHub (pinned to 75dd419e61)
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.
Example fix
// before: any non-404 failure aborts with a generic message
if (!res.ok && res.status !== 404) throw new Error(`Failed to delete session (${res.status})`);
// after: tolerate 404 and transient 5xx with one retry
if (!res.ok && res.status !== 404) {
if (res.status >= 500) await fetch(url, { method: 'DELETE', credentials: 'include' });
else throw new Error(`Failed to delete session (${res.status})`);
} Defensive patterns
Strategy: try-catch
Validate before calling
const sessions = await fetchUserSessions(baseUrl); if (!sessions.some(s => s.id === sessionId)) return; // already gone — skip the DELETE
Type guard
function isSessionId(v: unknown): v is string {
return typeof v === 'string' && v.length > 0;
} Try / catch
try {
await deleteUserSession(baseUrl, sessionId);
} catch (err) {
const status = Number((err as Error).message.match(/\((\d{3})\)/)?.[1] ?? 0);
if (status >= 500) await deleteUserSession(baseUrl, sessionId); // idempotent: 404 tolerated
else if (status === 401 || status === 403) await reauthAndRetry();
else toast.error('Could not remove session');
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Failed to load repository settings (${res.status})
- Failed to rename session (${res.status})
- Agent Learning request failed (${response.status})
- Failed to get file content type
- Slack OAuth HTTP error: ${tokenResponse.status} ${tokenRespo
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/b40e161c7d19ef00.
Report an issue: GitHub.