useListOrganizations: This expression is not callable. #1513

Closed
opened 2026-03-13 08:44:33 -05:00 by GiteaMirror · 11 comments
Owner

Originally created by @tkjaergaard on GitHub (Jul 17, 2025).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

When trying to call the useListOrganizations() i get a types error stating that it's not callable.

export function useAuthClient() {
  const url = useRequestURL()
  const headers = import.meta.server ? useRequestHeaders() : undefined

  const client = createAuthClient({
    baseURL: url.origin,
    plugins: [adminClient(), organizationClient(), passkeyClient()],
    fetchOptions: {
      headers,
    },
  })

  return {
    client,
  }
}
<script setup lang="ts">
const { client } = useAuthClient()

const organizations = await client.useListOrganizations()
</script>

<template>
  <div></div>
</template>

Current vs. Expected behavior

Getting a typescript error:

this expression is not callable.
  Type 'PreinitializedWritableAtom<{ data: { id: string; name: string; createdAt: Date; slug: string; metadata?: any; logo?: string | null | undefined; }[] | null; error: BetterFetchError | null; isPending: boolean; isRefetching: boolean; refetch: () => void; }>' has no call signatures.

What version of Better Auth are you using?

1.2.12

Provide environment information

- OS: MacOS 15.5
- Browser: Chrome 138.0.7204.101

Which area(s) are affected? (Select all that apply)

Types

Auth config (if applicable)

import { betterAuth } from 'better-auth'
import { admin, organization } from 'better-auth/plugins'
import { passkey } from 'better-auth/plugins/passkey'

export const auth = betterAuth({
    // ...
    plugins: [admin(), organization(), passkey()],
    emailAndPassword: {
      enabled: true,
      requireEmailVerification: false,
      autoSignIn: true,
    },
    user: {
      changeEmail: {
        enabled: true,
      },
    },
  })

Additional context

Using Nuxt 4.0.0

Originally created by @tkjaergaard on GitHub (Jul 17, 2025). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce When trying to call the useListOrganizations() i get a types error stating that it's not callable. ```ts export function useAuthClient() { const url = useRequestURL() const headers = import.meta.server ? useRequestHeaders() : undefined const client = createAuthClient({ baseURL: url.origin, plugins: [adminClient(), organizationClient(), passkeyClient()], fetchOptions: { headers, }, }) return { client, } } ``` ```vue <script setup lang="ts"> const { client } = useAuthClient() const organizations = await client.useListOrganizations() </script> <template> <div></div> </template> ``` ### Current vs. Expected behavior Getting a typescript error: ``` this expression is not callable. Type 'PreinitializedWritableAtom<{ data: { id: string; name: string; createdAt: Date; slug: string; metadata?: any; logo?: string | null | undefined; }[] | null; error: BetterFetchError | null; isPending: boolean; isRefetching: boolean; refetch: () => void; }>' has no call signatures. ``` ### What version of Better Auth are you using? 1.2.12 ### Provide environment information ```bash - OS: MacOS 15.5 - Browser: Chrome 138.0.7204.101 ``` ### Which area(s) are affected? (Select all that apply) Types ### Auth config (if applicable) ```typescript import { betterAuth } from 'better-auth' import { admin, organization } from 'better-auth/plugins' import { passkey } from 'better-auth/plugins/passkey' export const auth = betterAuth({ // ... plugins: [admin(), organization(), passkey()], emailAndPassword: { enabled: true, requireEmailVerification: false, autoSignIn: true, }, user: { changeEmail: { enabled: true, }, }, }) ``` ### Additional context Using Nuxt 4.0.0
GiteaMirror added the nuxt label 2026-03-13 08:44:33 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Jul 17, 2025):

Hi @tkjaergaard! I'm Dosu and I’m helping the better-auth team.

The error happens because useListOrganizations is not a function, but a reactive store (specifically a PreinitializedWritableAtom). You should not call it with parentheses or await it. Instead, assign it directly and use its properties reactively.

For Nuxt 4 + Vue 3 with <script setup>, the correct usage looks like this:

<script setup lang="ts">
const { authClient } = useAuthClient() // Make sure you're using 'authClient', not 'client'
const organizations = authClient.useListOrganizations
</script>

<template>
  <div v-if="organizations.data">
    <div v-for="org in organizations.data" :key="org.id">
      {{ org.name }}
    </div>
  </div>
  <div v-else-if="organizations.isPending">Loading...</div>
  <div v-else-if="organizations.error">Error: {{ organizations.error.message }}</div>
</template>

You can access organizations.data, organizations.isPending, and organizations.error reactively in your template. This pattern is confirmed in the official docs and code examples—see this documentation update and the organization plugin source.

There are no alternative methods for listing organizations on the client; this is the intended and supported approach.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Join Discord Share on X

@dosubot[bot] commented on GitHub (Jul 17, 2025): <!-- Greeting --> Hi @tkjaergaard! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> The error happens because `useListOrganizations` is not a function, but a reactive store (specifically a PreinitializedWritableAtom). You should not call it with parentheses or `await` it. Instead, assign it directly and use its properties reactively. For Nuxt 4 + Vue 3 with `<script setup>`, the correct usage looks like this: ```vue <script setup lang="ts"> const { authClient } = useAuthClient() // Make sure you're using 'authClient', not 'client' const organizations = authClient.useListOrganizations </script> <template> <div v-if="organizations.data"> <div v-for="org in organizations.data" :key="org.id"> {{ org.name }} </div> </div> <div v-else-if="organizations.isPending">Loading...</div> <div v-else-if="organizations.error">Error: {{ organizations.error.message }}</div> </template> ``` You can access `organizations.data`, `organizations.isPending`, and `organizations.error` reactively in your template. This pattern is confirmed in the official docs and code examples—see [this documentation update](https://github.com/better-auth/better-auth/pull/2308) and [the organization plugin source](https://github.com/better-auth/better-auth/blob/0c4583c015807077cbded89e089f59f7d3d67b48/packages/better-auth/src/plugins/organization/client.ts). There are no alternative methods for listing organizations on the client; this is the intended and supported approach. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/1e36bbd3-8f60-4032-8ecf-1407f4276d28?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/1e36bbd3-8f60-4032-8ecf-1407f4276d28?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/1e36bbd3-8f60-4032-8ecf-1407f4276d28?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/1e36bbd3-8f60-4032-8ecf-1407f4276d28?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/1e36bbd3-8f60-4032-8ecf-1407f4276d28?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/1e36bbd3-8f60-4032-8ecf-1407f4276d28?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/1e36bbd3-8f60-4032-8ecf-1407f4276d28?feedback_type=other)</sup>&nbsp;&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/3425)
Author
Owner

@Kinfe123 commented on GitHub (Jul 17, 2025):

i can see that you have not exported the auth client. where is the client is imported from ?

@Kinfe123 commented on GitHub (Jul 17, 2025): i can see that you have not exported the auth client. where is the client is imported from ?
Author
Owner

@tkjaergaard commented on GitHub (Jul 18, 2025):

@Kinfe123 yeah - i just took out the piece of relevance, in order to explain the current setup. I guess that the config in it self is not that relevant here since it's a potential types error?

The client is being loaded through the useAuthClient hook - i've updated the code in the issue.

@tkjaergaard commented on GitHub (Jul 18, 2025): @Kinfe123 yeah - i just took out the piece of relevance, in order to explain the current setup. I guess that the config in it self is not that relevant here since it's a potential types error? The client is being loaded through the useAuthClient hook - i've updated the code in the issue.
Author
Owner

@tkjaergaard commented on GitHub (Jul 18, 2025):

Hi @tkjaergaard! I'm Dosu and I’m helping the better-auth team.

The error happens because useListOrganizations is not a function, but a reactive store (specifically a PreinitializedWritableAtom). You should not call it with parentheses or await it. Instead, assign it directly and use its properties reactively.

For Nuxt 4 + Vue 3 with <script setup>, the correct usage looks like this:

<script setup lang="ts"> const { authClient } = useAuthClient() // Make sure you're using 'authClient', not 'client' const organizations = authClient.useListOrganizations </script>
{{ org.name }}
Loading...
Error: {{ organizations.error.message }}
You can access `organizations.data`, `organizations.isPending`, and `organizations.error` reactively in your template. This pattern is confirmed in the official docs and code examples—see [this documentation update](https://github.com/better-auth/better-auth/pull/2308) and [the organization plugin source](0c4583c015/packages/better-auth/src/plugins/organization/client.ts).

There are no alternative methods for listing organizations on the client; this is the intended and supported approach.

To reply, just mention @dosu.

How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Join Discord Share on X

According to the Vue documentation it's a function https://www.better-auth.com/docs/plugins/organization#list-users-organizations

@tkjaergaard commented on GitHub (Jul 18, 2025): > Hi [@tkjaergaard](https://github.com/tkjaergaard)! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. > > The error happens because `useListOrganizations` is not a function, but a reactive store (specifically a PreinitializedWritableAtom). You should not call it with parentheses or `await` it. Instead, assign it directly and use its properties reactively. > > For Nuxt 4 + Vue 3 with `<script setup>`, the correct usage looks like this: > > <script setup lang="ts"> > const { authClient } = useAuthClient() // Make sure you're using 'authClient', not 'client' > const organizations = authClient.useListOrganizations > </script> > > <template> > <div v-if="organizations.data"> > <div v-for="org in organizations.data" :key="org.id"> > {{ org.name }} > </div> > </div> > <div v-else-if="organizations.isPending">Loading...</div> > <div v-else-if="organizations.error">Error: {{ organizations.error.message }}</div> > </template> > You can access `organizations.data`, `organizations.isPending`, and `organizations.error` reactively in your template. This pattern is confirmed in the official docs and code examples—see [this documentation update](https://github.com/better-auth/better-auth/pull/2308) and [the organization plugin source](https://github.com/better-auth/better-auth/blob/0c4583c015807077cbded89e089f59f7d3d67b48/packages/better-auth/src/plugins/organization/client.ts). > > There are no alternative methods for listing organizations on the client; this is the intended and supported approach. > > _To reply, just mention [@dosu](https://go.dosu.dev/dosubot)._ > > How did I do? [Good](https://app.dosu.dev/response-feedback/1e36bbd3-8f60-4032-8ecf-1407f4276d28?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/1e36bbd3-8f60-4032-8ecf-1407f4276d28?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/1e36bbd3-8f60-4032-8ecf-1407f4276d28?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/1e36bbd3-8f60-4032-8ecf-1407f4276d28?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/1e36bbd3-8f60-4032-8ecf-1407f4276d28?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/1e36bbd3-8f60-4032-8ecf-1407f4276d28?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/1e36bbd3-8f60-4032-8ecf-1407f4276d28?feedback_type=other)  [![Join Discord](https://camo.githubusercontent.com/d562c2df5e4567ea41d37f1d91a4da0839d8341037045b103b2da268998de17f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6a6f696e2d3538363546323f6c6f676f3d646973636f7264266c6f676f436f6c6f723d7768697465266c6162656c3d)](https://go.dosu.dev/discord-bot) [![Share on X](https://camo.githubusercontent.com/4649f705e2396d6f328dbc8e800a0509c9c17b3b20253b36706c393df124b93d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f582d73686172652d626c61636b)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/3425) According to the Vue documentation it's a function https://www.better-auth.com/docs/plugins/organization#list-users-organizations
Author
Owner

@mathieumagalhaes commented on GitHub (Jul 18, 2025):

I'm having the same issue with fetchOptions.
It seems that authClient.organization is untyped when fetchOptions is passed.
When I remove the fetchOptions, it is typed again.

I've tried v1.2.10 and v1.3.0-beta.9

@mathieumagalhaes commented on GitHub (Jul 18, 2025): I'm having the same issue with `fetchOptions`. It seems that `authClient.organization` is untyped when `fetchOptions` is passed. When I remove the `fetchOptions`, it is typed again. I've tried _v1.2.10_ and _v1.3.0-beta.9_
Author
Owner

@Kinfe123 commented on GitHub (Aug 1, 2025):

I wasn’t able to reproduce the issue on my end. If you have a minimal reproducible example, that would be super helpful. Also, it looks like you’re recreating the auth client on every call.

@Kinfe123 commented on GitHub (Aug 1, 2025): I wasn’t able to reproduce the issue on my end. If you have a minimal reproducible example, that would be super helpful. Also, it looks like you’re recreating the auth client on every call.
Author
Owner

@aliou commented on GitHub (Aug 1, 2025):

Having the same issue for useSession and useActiveOrganization. I created a minimal example here: https://github.com/aliou/better-auth-repro-1.3.4 and you can see the error when running typecheck here: https://github.com/aliou/better-auth-repro-1.3.4/actions/runs/16679837163/job/47215549454

Edit: Sorry, forgot to mention, I've seen this on 1.3.3 and the repro is on 1.3.4.

@Kinfe123 let me know if you need more information. Thanks!

Edit 2: Also, this is with React but it seems like it's the same issue as OP.

@aliou commented on GitHub (Aug 1, 2025): Having the same issue for `useSession` and `useActiveOrganization`. I created a minimal example here: https://github.com/aliou/better-auth-repro-1.3.4 and you can see the error when running typecheck here: https://github.com/aliou/better-auth-repro-1.3.4/actions/runs/16679837163/job/47215549454 Edit: Sorry, forgot to mention, I've seen this on 1.3.3 and the repro is on 1.3.4. @Kinfe123 let me know if you need more information. Thanks! Edit 2: Also, this is with React but it seems like it's the same issue as OP.
Author
Owner

@ping-maxwell commented on GitHub (Aug 23, 2025):

@aliou change your import from

import { createAuthClient } from "better-auth/client";

to

import { createAuthClient } from "better-auth/react";
@ping-maxwell commented on GitHub (Aug 23, 2025): @aliou change your import from ```ts import { createAuthClient } from "better-auth/client"; ``` to ```ts import { createAuthClient } from "better-auth/react"; ```
Author
Owner

@Eazash commented on GitHub (Aug 29, 2025):

@tkjaergaard Make sure to import createAuthClient from better-auth/vue. I'm not completely sure since it's not specified in your issue description, but it seems to be that you have used import {createAuthClient} from 'better-auth/client' in your useAuthClient composable.

@Kinfe123 I have been able to create a reproduction (https://codesandbox.io/p/devbox/festive-microservice-qs7rrn?file=%2Fapp%2Fapp.vue%3A8%2C1). Since @aliou has also been facing this issue but in a react context, I believe the root cause might be that the types for useListOrganizations are being incorrectly reported as a PreinitializedWritableAtom while it's runtime type is of a function

@Eazash commented on GitHub (Aug 29, 2025): @tkjaergaard Make sure to import `createAuthClient` from `better-auth/vue`. I'm not completely sure since it's not specified in your issue description, but it seems to be that you have used `import {createAuthClient} from 'better-auth/client'` in your `useAuthClient` composable. @Kinfe123 I have been able to create a reproduction (https://codesandbox.io/p/devbox/festive-microservice-qs7rrn?file=%2Fapp%2Fapp.vue%3A8%2C1). Since @aliou has also been facing this issue but in a react context, I believe the root cause might be that the types for `useListOrganizations` are being incorrectly reported as a `PreinitializedWritableAtom` while it's runtime type is of a function
Author
Owner

@jesuscelemin commented on GitHub (Sep 18, 2025):

Fix: Better Auth useListOrganizations Hook Error
Problem

When using Better Auth's organization plugin in Next.js, you might encounter this TypeScript error when trying to use the useListOrganizations hook:

This expression is not callable. Type 'PreinitializedWritableAtom<{ data: Prettify<{ id: string; name: string; slug: string; createdAt: Date; logo?: string | null | undefined; metadata?: any; } & { members: ({ id: string; organizationId: string; userId: string; role: string; createdAt: Date; } & { ...; })[]; invitations: { ...; }[]; }> | null; error: Bet...' has no call signatures.ts(2349)

Solution

The useListOrganizations export from Better Auth is a Jotai atom, not a React hook. To access its value, you need to use the .get() method:

// Correct way
const { data: activeOrganization } = useClient.useListOrganizations.get();

@jesuscelemin commented on GitHub (Sep 18, 2025): Fix: Better Auth useListOrganizations Hook Error Problem When using Better Auth's organization plugin in Next.js, you might encounter this TypeScript error when trying to use the useListOrganizations hook: > `This expression is not callable. Type 'PreinitializedWritableAtom<{ data: Prettify<{ id: string; name: string; slug: string; createdAt: Date; logo?: string | null | undefined; metadata?: any; } & { members: ({ id: string; organizationId: string; userId: string; role: string; createdAt: Date; } & { ...; })[]; invitations: { ...; }[]; }> | null; error: Bet...' has no call signatures.ts(2349)` Solution The useListOrganizations export from Better Auth is a Jotai atom, not a React hook. To access its value, you need to use the .get() method: // ✅ Correct way `const { data: activeOrganization } = useClient.useListOrganizations.get();`
Author
Owner

@dosubot[bot] commented on GitHub (Dec 18, 2025):

Hi, @tkjaergaard. I'm Dosu, and I'm helping the better-auth team manage their backlog and am marking this issue as stale.

Issue Summary:

  • You reported a TypeScript error caused by calling useListOrganizations() as a function instead of using it as a reactive store.
  • The core issue is treating a PreinitializedWritableAtom as callable, which it is not.
  • Other users experienced similar typing issues across React and Vue, often due to incorrect imports of createAuthClient.
  • A workaround involves using the .get() method on the atom to access data, addressing the runtime vs. TypeScript type mismatch.
  • The resolution is to use the store without parentheses and ensure correct imports from better-auth/vue or better-auth/react.

Next Steps:

  • Please confirm if this issue is still relevant with the latest version of better-auth; if so, feel free to comment to keep the discussion open.
  • Otherwise, I will automatically close this issue in 7 days.

Thank you for your understanding and contribution!

@dosubot[bot] commented on GitHub (Dec 18, 2025): Hi, @tkjaergaard. I'm [Dosu](https://dosu.dev), and I'm helping the better-auth team manage their backlog and am marking this issue as stale. **Issue Summary:** - You reported a TypeScript error caused by calling `useListOrganizations()` as a function instead of using it as a reactive store. - The core issue is treating a `PreinitializedWritableAtom` as callable, which it is not. - Other users experienced similar typing issues across React and Vue, often due to incorrect imports of `createAuthClient`. - A workaround involves using the `.get()` method on the atom to access data, addressing the runtime vs. TypeScript type mismatch. - The resolution is to use the store without parentheses and ensure correct imports from `better-auth/vue` or `better-auth/react`. **Next Steps:** - Please confirm if this issue is still relevant with the latest version of better-auth; if so, feel free to comment to keep the discussion open. - Otherwise, I will automatically close this issue in 7 days. Thank you for your understanding and contribution!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#1513