Zachoo
Zachoo4mo ago

Onboarding Flow Clerk x Convex Multitenant

Hi everyone, I’m working on a multi-tenant app using Convex and Clerk. Currently, I have an onboarding flow that creates an organization in Clerk (which works fine). Once the organization is created, I then create a site entry in my database. For this process, I use the following code to get the current orgId:
const identity = await ctx.auth.getUserIdentity();
if (!identity) {
throw new Error("Not authenticated");
}
const organizationId = identity.orgId;
if (!organizationId) {
throw new Error("No organization ID found");
}
const identity = await ctx.auth.getUserIdentity();
if (!identity) {
throw new Error("Not authenticated");
}
const organizationId = identity.orgId;
if (!organizationId) {
throw new Error("No organization ID found");
}
The goal is to retrieve the orgId on the server so I can attach it to the data being indexed, which is part of the multi-tenant architecture. The Issue: Currently, when I go through the onboarding process, the organization is created successfully. However, when I attempt to add the site, I encounter the following error:
site:createOrUpdateSite
failure
70ms
Uncaught Error: No organization ID found
at handler (../convex/site.tsx:28:4)
site:createOrUpdateSite
failure
70ms
Uncaught Error: No organization ID found
at handler (../convex/site.tsx:28:4)
If I refresh and remove the onboarded flag, and then repeat the process, the site is created successfully but it uses the orgId of a different organization (the default one selected). Can anyone help with this issue? It seems like the orgId isn’t being retrieved correctly during the site creation process. Thanks!
1 Reply
Zachoo
ZachooOP4mo ago
Resolved: Add a key to the convex clerk provider to force a refresh
export function ConvexClientProvider({ children }: { children: ReactNode }) {
const orgId = useAuth().orgId;

return (
<ConvexProviderWithClerk key={orgId} client={convex} useAuth={useAuth}>
{children}
</ConvexProviderWithClerk>
);
}
export function ConvexClientProvider({ children }: { children: ReactNode }) {
const orgId = useAuth().orgId;

return (
<ConvexProviderWithClerk key={orgId} client={convex} useAuth={useAuth}>
{children}
</ConvexProviderWithClerk>
);
}
The org id is pulled from clerk so responds to updates from clerk client components. Then you can add org to custom claims in JWT and use this to protect actions in functions on convex server side.