paperclipai/paperclip · error
${(payload as { error?: string } | null)?.error ?? `Failed t
Error message
${(payload as { error?: string } | null)?.error ?? `Failed to load profile (${res.status})`} What it means
The auth API's loadProfile method throws this Error when GET /profile returns a non-OK HTTP status. It prefers a server-provided `error` string from the JSON body and falls back to a generic message including the HTTP status. Before throwing, it gives tenantSessionRecovery a chance to handle tenant/session recovery instead of surfacing the error.
Source
Thrown at ui/src/api/auth.ts:189
signInEmail: async (input: { email: string; password: string }) => {
await authPost("/sign-in/email", input);
},
signUpEmail: async (input: { name: string; email: string; password: string }) => {
await authPost("/sign-up/email", input);
},
getProfile: async (): Promise<CurrentUserProfile> => {
const res = await fetch("/api/auth/profile", {
credentials: "include",
headers: { Accept: "application/json" },
});
const payload = await res.json().catch(() => null);
if (!res.ok) {
const recovery = tenantSessionRecovery.recoverIfNeeded(res.status, payload);
if (recovery) return recovery;
throw new Error((payload as { error?: string } | null)?.error ?? `Failed to load profile (${res.status})`);
}
return currentUserProfileSchema.parse(payload);
},
updateProfile: async (input: UpdateCurrentUserProfile): Promise<CurrentUserProfile> =>
authPatch("/profile", input, (payload) => currentUserProfileSchema.parse(payload)),
signOut: async (): Promise<SignOutResult | null> => {
const payload = await authPost("/sign-out", {});
if (!payload || typeof payload !== "object") return null;
const result = payload as Record<string, unknown>;
return {
...(typeof result.success === "boolean" ? { success: result.success } : {}),
...(typeof result.redirectTo === "string" ? { redirectTo: result.redirectTo } : {}),
};
},
};View on GitHub (pinned to 01ad858492)
Solutions
- Check network tab for the actual status/body of the profile request
- If 401, re-authenticate or let tenantSessionRecovery run its recovery flow
- If the body has no `error` field, fix the server route to return `{ error: string }` on failure
- Verify the API server is running and /api/health passes
Example fix
// before
throw new Error((payload as { error?: string } | null)?.error ?? `Failed to load profile (${res.status})`);
// after
if (res.status === 401) { await refreshSession(); return loadProfile(); }
throw new Error((payload as { error?: string } | null)?.error ?? `Failed to load profile (${res.status})`); Defensive patterns
Strategy: try-catch
Validate before calling
const ok = typeof navigator !== 'undefined' && navigator.onLine;
Type guard
function hasServerError(p: unknown): p is { error: string } { return typeof p === 'object' && p !== null && typeof (p as any).error === 'string'; } Try / catch
try { const profile = await authApi.loadProfile(); } catch (e) { if (/\(401\)/.test(e.message) || /Failed to load profile/.test(e.message)) redirectToLogin(); else showToast(e.message); } Prevention
- Always check res.ok before parsing profile payloads
- Keep tenantSessionRecovery wired for 401/403 handling
- Return structured `{ error }` bodies from all auth routes
- Add retry-with-backoff for 5xx profile loads
When it happens
Trigger: The /api/auth/profile (or equivalent) endpoint returns 401/403/404/500; the response body is not JSON (json().catch returns null), so the fallback message with status is used; the server returns an error envelope `{ error: "..." }`.
Common situations: Expired or invalid session cookie hitting the profile endpoint, user deleted while a tab stays open, API server restarting behind a proxy returning 502, tenant mismatch after an org switch.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- OpenCode API ${path} request failed: ${redact(String(error),
- OpenCode API ${path} returned HTTP ${response.status}: ${red
- Discord ${operation} failed (HTTP ${response.status}${code ?
- ${(errorBody as { error?: string } | null)?.error ?? `Reques
- ${payload?.error ?? `Failed to load health (${res.status})`}
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/a44f58a2dd99798a.
Report an issue: GitHub.