different-ai/openwork · error · OrganizationNotFoundError

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

Error message

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

What it means

loadOrgContext GETs /v1/org with the ORG_SCOPE_HEADER set to the organizationId and throws this plain Error for any non-ok status except 404 (404 throws OrganizationNotFoundError instead — see error 1113's sibling branch). It means the org-scoped context (settings, roles) could not be fetched for the active organization.

Source

Thrown at ee/apps/den-web/app/(den)/dashboard/_providers/org-dashboard-provider.tsx:183

      },
      12000,
    );

    if (!response.ok) {
      throw new Error(getErrorMessage(payload, `Failed to switch organization (${response.status}).`));
    }
  }

  async function loadOrgContext(organizationId: string, refreshRoles: boolean) {
    const path = refreshRoles ? "/v1/org?refreshRoles=true" : "/v1/org";
    const { response, payload } = await requestJson(
      path,
      { method: "GET", headers: { [ORG_SCOPE_HEADER]: organizationId } },
      12000,
    );
    if (!response.ok) {
      if (response.status === 404) {
        throw new OrganizationNotFoundError(getErrorMessage(payload, `Failed to load organization (${response.status}).`));
      }

      throw new Error(getErrorMessage(payload, `Failed to load organization (${response.status}).`));
    }

    const parsed = parseOrgContextPayload(payload);
    if (!parsed) {
      throw new Error("Organization context response was incomplete.");
    }

    return parsed;
  }

  async function restoreDisplayedOrganization() {
    const displayedOrgId = orgContext?.organization.id;
    if (!displayedOrgId) {
      return;
    }

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Check the interpolated status: 403 → confirm membership server-side and prompt the user to switch organizations.
  2. 401 → re-authenticate (sign-in flow) before retrying the context load.
  3. Inspect the ORG_SCOPE_HEADER value being sent; a null/undefined id produces 400s — restore from the org list instead.
  4. For 5xx, check den-api logs and retry with backoff; context loads are read-only so retries are safe.
  5. Wrap the context loader in the UI's org error boundary and offer refreshOrgData as recovery.

Example fix

// before
const parsed = await loadOrgContext(orgId, false); // throws generic error on 403
// after
try {
  const parsed = await loadOrgContext(orgId, false);
} catch (err) {
  if (err instanceof OrganizationNotFoundError || String(err).includes("403")) {
    await refreshOrgData(); // drop inaccessible org, select another
  } else throw err;
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!organizationId) { await refreshOrgData(); return; } // don't call with a blank scope header

Type guard

function hasOrgScope(o: unknown): o is { organizationId: string } {
  return typeof o === "object" && o !== null && typeof (o as { organizationId?: unknown }).organizationId === "string" && o.organizationId.length > 0;
}

Try / catch

try {
  await loadOrgContext(orgId, false);
} catch (err) {
  if (err instanceof OrganizationNotFoundError || String(err.message).includes("403")) {
    await refreshOrgData();
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: GET /v1/org returns 401 (expired session), 403 (user lost access / role revoked for this org), 500/503 (server error), or 400 (invalid ORG_SCOPE_HEADER value) — anything other than 404.

Common situations: User's admin revoked their membership mid-session; Den server returning 5xx during deploy or DB migration; client sending a malformed org id header after bad state restore.

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/6f5aa92b67ec1651. Report an issue: GitHub.