Skip to content

publicMetadata from createInvitationBulk not transferred to user on signup #7956

@HamedBahram

Description

@HamedBahram

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

  1. 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
  }
])
  1. Invitee receives the email and completes signup
  2. 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 (publicMetadatapublic_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 publicMetadata after signup

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