Skip to content

useOrganizationList returns empty data despite API responding with full list (@clerk/nextjs 7.0.12) #8559

@misterludden

Description

@misterludden

Summary

In @clerk/nextjs@7.0.12 (Next.js 16.2.0, React 19.2.4), useOrganizationList({ userMemberships: true }) and useOrganizationList({ userMemberships: { infinite: true } }) both return { data: [], count: 0, isLoading: false, hasNextPage: false } even when the underlying /v1/me/organization_memberships REST endpoint responds 200 with total_count: 2 and both memberships in data[].

The lower-level method on the user object — user.getOrganizationMemberships() — works correctly and returns the full list. This is the workaround we're using.

Environment

  • @clerk/nextjs: 7.0.12
  • @clerk/backend: 3.4.6
  • @clerk/testing: 2.0.26
  • next: 16.2.0
  • react / react-dom: 19.2.4
  • Clerk JS version reported in network request: _clerk_js_version=6.11.0
  • Clerk API version: 2025-11-10
  • Headless Chromium 147 (Playwright) and standard Chrome browsers reproduce.

Repro

  1. User signs into a Clerk dev instance.
  2. The user is an admin of exactly 2 orgs (created via Backend SDK client.organizations.createOrganization({ createdBy: userId, ... }) with no further user invites needed).
  3. In a React component using @clerk/nextjs:
const { userMemberships } = useOrganizationList({
  userMemberships: true, // or { infinite: true } — both reproduce
});
useEffect(() => {
  console.log('hook:', {
    isLoading: userMemberships?.isLoading,
    dataLen: userMemberships?.data?.length,
    count: userMemberships?.count,
  });
}, [userMemberships]);

Output:

hook: { isLoading: false, dataLen: 0, count: 0 }

But — same user, same component, same session:

const { user } = useUser();
useEffect(() => {
  user?.getOrganizationMemberships().then((m) => {
    console.log('user.method:', m?.data?.length); // → 2 ✓
  });
}, [user]);

And the underlying network call (captured by Playwright network trace) shows:

GET https://<instance>.clerk.accounts.dev/v1/me/organization_memberships?paginated=true&limit=10&offset=0
Status: 200
Body: { "response": { "data": [m1, m2], "total_count": 2 } }

Both memberships in the response have role: "org:admin", full permissions, no banned flag, identical public_user_data.user_id matching the signed-in user.

Expected

useOrganizationList({ userMemberships: true }).userMemberships.data should be [m1, m2] matching the API response.

Actual

userMemberships.data is empty ([]). count is 0. isLoading is false. hasNextPage is false. As if the API returned an empty list, but the network trace proves otherwise.

Workaround

const { user } = useUser();
const { setActive } = useOrganizationList(); // still used for switching
const [orgs, setOrgs] = useState<Membership[] | null>(null);

useEffect(() => {
  if (!user) return;
  let cancelled = false;
  user.getOrganizationMemberships().then((memberships) => {
    if (!cancelled) {
      const items = Array.isArray(memberships) ? memberships : memberships?.data ?? [];
      setOrgs(items);
    }
  });
  return () => { cancelled = true; };
}, [user]);

This works correctly. We applied it in our org-switcher component and the multi-org UI now renders both memberships.

Notes

  • Reproduces against a Clerk dev instance with a long-lived test user that's recreated via Backend SDK between e2e runs.
  • The bug surfaces in a fresh-sign-in flow where both orgs were created shortly before sign-in. We haven't tested whether older sessions (where orgs existed for hours/days before sign-in) reproduce.
  • We have a full reproducible end-to-end via Playwright + Clerk Testing Tokens if helpful.

Happy to provide more detail or test a fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions