Inconsistent users.createToken RestAPI error

Description

I’m running into an intermittent issue with the users.createToken API endpoint. Sometimes it works, but other times I get this error:

{"success":false,"error":"Cannot read properties of undefined (reading 'tokens')"}

Here’s the command I’m using (removed sensitive info for security):

curl -X POST "https://rocketchat.example.com/api/v1/users.createToken" \
  -H "X-Auth-Token: [my-auth-token]" \
  -H "X-User-Id: [my-user-id]" \
  -H "Content-Type: application/json" \
  --data '{"username":"player_01"}'

The strange part is that retrying the command often makes it work. :thinking: Has anyone else encountered this, or does anyone have tips for troubleshooting this inconsistency?

Server Setup Information

  • Version of Rocket.Chat Server: 7.0.0
  • Operating System: Ubuntu
  • Deployment Method: Docker on AWS
  • Number of Running Instances: 1

As per this - please don’t duplicate things. It gets hard to follow and you get ignored.

https://open.rocket.chat/channel/support?msg=HwN2c8EYZoRAunnv7

I suspect this issue is a MongoDB race condition. It seems like the user’s token isn’t yet available during the users.createToken call. I’m running users.create immediately before users.createToken, so my workaround was to just retry the createToken call until it works.

async function generateUserToken(adminUserId, adminAuthToken, username, server ) {
    const maxRetries = 30;
    const retryInterval = 1000; // 1 second
    let attempts = 0;

    while (attempts < maxRetries) {
        attempts++;
        const userExists = await checkUserExists(adminUserId, adminAuthToken, username, server);

        if (userExists) {
            try {
                const url = `https://${server}/api/v1/users.createToken`;
                const headers = {
                    'X-User-Id': adminUserId,
                    'X-Auth-Token': adminAuthToken,
                    'Content-Type': 'application/json'
                };

                console.log(`Attempt ${attempts}: Generating user token for ${username}`);
                const response = await fetch(url, {
                    method: 'POST',
                    headers: headers,
                    body: JSON.stringify({ username })
                });

                const data = await response.json();
                console.log('Full response data:', data);

                if (data.success && data.data && data.data.authToken) {
                    const userId = data.data.userId;
                    const authToken = data.data.authToken;
                    console.log('Token generated successfully:', { authToken, userId });
                    return { authToken, userId };
                } else {
                    throw new Error(`Token generation failed: ${JSON.stringify(data)}`);
                }
            } catch (error) {
                console.error(`Error generating user token (attempt ${attempts}):`, error);
            }
        } else {
            console.log(`User ${username} does not exist yet. Waiting ${retryInterval}ms before retrying...`);
        }

        await sleep(retryInterval);
    }

    throw new Error(`Failed to generate user token for ${username} after ${maxRetries} attempts`);
}

I posted my solution below. Thanks