different-ai/openwork · error

Failed to load organizations (${response.status}).

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.

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)

Solutions

  1. Check the interpolated status in the message: 401/403 → re-authenticate (sign in again to refresh the Den session cookie).
  2. 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.
  3. Verify den-web's API base URL / reverse-proxy routes point at a den-api version that still serves /v1/me/orgs.
  4. For 5xx, inspect den-api server logs for the corresponding request; fix upstream DB/upstream dependency and retry.
  5. 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

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


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/bc689d2bc2bb6c99. Report an issue: GitHub.