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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions