different-ai/openwork · error
Failed to load organizations
Error message
Failed to load organizations (${response.status}). What it means
loadOrgDirectory fetches GET /v1/me/orgs (12s timeout) and throws this error whenever the HTTP response is not ok. The message interpolates the HTTP status; a server-provided error message (via getErrorMessage) takes precedence when present. It signals the dashboard could not retrieve the user's organization list, so the org directory payload cannot be built.
Solutions
- Check the interpolated status in the message: 401/403 → re-authenticate (sign in again to refresh the Den session cookie).
- Call the endpoint directly (curl -i /v1/me/orgs with the session cookie) to see the raw body and confirm the server-side error detail.
- Verify den-web's API base URL / reverse-proxy routes point at a den-api version that still serves /v1/me/orgs.
- For 5xx, inspect den-api server logs for the corresponding request; fix upstream DB/upstream dependency and retry.
- If the network is flaky, add a retry/backoff wrapper around refreshOrgData since requestJson enforces a hard 12s timeout.
Example fix
// before
const { response, payload } = await requestJson("/v1/me/orgs", { method: "GET" }, 12000);
if (!response.ok) {
throw new Error(getErrorMessage(payload, `Failed to load organizations (${response.status}).`));
}
// after
const { response, payload } = await requestJson("/v1/me/orgs", { method: "GET" }, 12000);
if (response.status === 401) {
await reauthenticate(); // refresh session then retry once
return loadOrgDirectory();
}
if (!response.ok) {
throw new Error(getErrorMessage(payload, `Failed to load organizations (${response.status}).`));
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight: ensure a session exists
const sessionOk = document.cookie.includes("den_session") ?? await checkSession();
if (!sessionOk) await signIn(); Type guard
function isOrgListPayload(p: unknown): p is { organizations: { slug: string; role: string }[] } {
return typeof p === "object" && p !== null && Array.isArray((p as { organizations?: unknown }).organizations);
} Try / catch
try {
await refreshOrgData();
} catch (err) {
if (String(err.message).includes("401")) redirectToSignIn();
else if (String(err.message).includes("404")) showApiVersionError();
else showRetryableError(err, () => refreshOrgData());
} Prevention
- Keep sessions alive; re-authenticate before long dashboard sessions.
- Pin den-web and den-api versions so /v1/me/orgs never disappears underneath the client.
- Add retry with backoff for 5xx on dashboard load.
- Monitor the interpolated status codes in this message for auth vs server trends.
- Test behind your production reverse proxy so stripped cookies surface in CI.
When it happens
Trigger: GET /v1/me/orgs returns 401/403 (expired or missing session cookie), 404/410 (route removed or version mismatch), 500/502/503 (server or upstream failure), or a network-level failure resolved by requestJson's timeout as a non-ok response.
Common situations: Users with stale Den sessions after server restart or token rotation; self-hosted deployments behind a proxy stripping auth cookies; API version drift between den-web and the den-api server causing 404s.
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
- Could not load egress diagnostics
- Egress diagnostic could not start
- Failed to create organization
- Failed to create skill
- Failed to delete skill
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/bc689d2bc2bb6c99.
Report an issue: GitHub.
Appendix: source
Thrown at ee/apps/den-web/app/(den)/dashboard/_providers/org-dashboard-provider.tsx:153
}
function ensureTargetIsNotOwner(memberId: string) {
const target = orgContext?.members.find((member) => member.id === memberId) ?? null;
if (target?.isOwner) {
throw new Error("The workspace owner cannot be changed or removed from this action.");
}
return target;
}
function shouldRefreshRolesForPage(org: DenOrgSummary) {
const isMembersPage = pathname === "/dashboard/members" || pathname === "/dashboard/manage-members";
return isMembersPage && getOrgAccessFlags(org.role, false).isAdmin;
}
async function loadOrgDirectory() {
const { response, payload } = await requestJson("/v1/me/orgs", { method: "GET" }, 12000);
if (!response.ok) {
throw new Error(getErrorMessage(payload, `Failed to load organizations (${response.status}).`));
}
return parseOrgListPayload(payload);
}
async function setActiveOrganization(input: { organizationId?: string | null; organizationSlug?: string | null }) {
const { response, payload } = await requestJson(
"/api/auth/organization/set-active",
{
method: "POST",
body: JSON.stringify(input),
},
12000,
);
if (!response.ok) {
throw new Error(getErrorMessage(payload, `Failed to switch organization (${response.status}).`));
}View on GitHub (pinned to 2b7df46e8a)