-
Notifications
You must be signed in to change notification settings - Fork 437
Description
Description
When using createInvitationBulk with publicMetadata, the metadata is not transferred to the Clerk user object after the invitee accepts the invitation and completes signup. The docs state:
Once an invitee accepts and completes signup, these metadata will end up in the user's public metadata.
This does not happen in practice.
Steps to reproduce
- Create bulk invitations with
publicMetadata:
const client = await clerkClient()
await client.invitations.createInvitationBulk([
{
emailAddress: 'agent@example.com',
publicMetadata: { role: 'agent' },
redirectUrl: 'https://example.com/admin',
ignoreExisting: true
}
])- Invitee receives the email and completes signup
- Check the created user's
publicMetadata— it is empty ({})
Expected behavior
The user's publicMetadata should contain { role: 'agent' } after signup, as documented.
SDK investigation
Verified the SDK serialization is correct. In @clerk/backend, createInvitationBulk passes bodyParams through the standard snakecase_keys formatter:
// InvitationAPI
async createInvitationBulk(params) {
return this.request({
method: "POST",
path: joinPaths(basePath, "bulk"),
bodyParams: params // no options override
});
}
// buildRequest serializer
const formatKeys = (object) => snakecase_keys(object, { deep: false });
body: JSON.stringify(Array.isArray(bodyParams) ? bodyParams.map(formatKeys) : formatKeys(bodyParams))The top-level keys are correctly converted (publicMetadata → public_metadata), and the nested metadata object ({ role: 'agent' }) doesn't require any conversion. The request body sent to the API is valid.
This suggests the issue is server-side — the bulk endpoint accepts public_metadata but does not propagate it to the user created after the invitation is accepted.
Workaround
Explicitly set publicMetadata via updateUserMetadata in the user.created webhook handler:
await clerkClient.users.updateUserMetadata(userId, {
publicMetadata: { role: 'agent' }
})Environment
@clerk/nextjs: 6.39.0@clerk/backend: 2.33.0- Node.js: 22
- Tested with 2 separate invitees, both had empty
publicMetadataafter signup