RocketChat/Rocket.Chat · error · Meteor.Error
error-token-already-exists
error-token-already-exists
Error message
A token with this name already exists
What it means
Personal access token names are unique per user. generatePersonalAccessTokenOfUser first looks up Users.findPersonalAccessTokenByTokenNameAndUserId({ userId, tokenName }); if a token with that name already exists for the user it aborts with error-token-already-exists before creating a new secret.
Solutions
- Choose a different, unique tokenName for the new token.
- If you want a new secret under the existing name, call personalAccessTokens:regenerateToken instead.
- Or remove the old token first with personalAccessTokens:removeToken, then generate.
Example fix
// before
await Meteor.callAsync('personalAccessTokens:generateToken', { tokenName: 'ci-deploy', bypassTwoFactor: false });
// after — name already used: rotate the secret instead
await Meteor.callAsync('personalAccessTokens:regenerateToken', { tokenName: 'ci-deploy' }); Defensive patterns
Strategy: validation
Validate before calling
const existing = await Users.findPersonalAccessTokenByTokenNameAndUserId({ userId, tokenName });
if (existing) {
// rotate instead: call personalAccessTokens:regenerateToken
} Try / catch
try {
await Meteor.callAsync('personalAccessTokens:generateToken', { tokenName, bypassTwoFactor: false });
} catch (e: any) {
if (e?.error === 'error-token-already-exists') {
await Meteor.callAsync('personalAccessTokens:regenerateToken', { tokenName }); // desired behavior: rotate
} else throw e;
} Prevention
- Fetch the user's existing token names before showing the create form
- Use regenerateToken for secret rotation; reserve generateToken for first creation
- Guard against double-submit in the UI
When it happens
Trigger: Calling personalAccessTokens:generateToken with a tokenName the same user already used — double-submitted create form, retry after a network failure, or simply forgetting an earlier token.
Common situations: CI scripts hard-coding a token name on every run, UI double-click on 'Add', rotating tokens by re-creating instead of regenerating.
Related errors
- duplicated-account
- error-business-hour-name-already-in-use
- error-duplicate-role-names-not-allowed
- error-duplicated-sla
- error-token-does-not-exists
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/dbcb2ffd5d7b1f09.
Report an issue: GitHub.
Appendix: source
Thrown at apps/meteor/imports/personal-access-tokens/server/api/methods/generateToken.ts:37
userId,
}: {
tokenName: string;
userId: string;
bypassTwoFactor: boolean;
}): Promise<string> => {
if (!(await hasPermissionAsync(userId, 'create-personal-access-tokens'))) {
throw new Meteor.Error('not-authorized', 'Not Authorized', {
method: 'personalAccessTokens:generateToken',
});
}
const token = Random.secret();
const tokenExist = await Users.findPersonalAccessTokenByTokenNameAndUserId({
userId,
tokenName,
});
if (tokenExist) {
throw new Meteor.Error('error-token-already-exists', 'A token with this name already exists', {
method: 'personalAccessTokens:generateToken',
});
}
await Users.addPersonalAccessTokenToUser({
userId,
loginTokenObject: {
hashedToken: Accounts._hashLoginToken(token),
type: 'personalAccessToken',
createdAt: new Date(),
lastTokenPart: token.slice(-6),
name: tokenName,
bypassTwoFactor,
},
});
return token;
};
View on GitHub (pinned to b2c16d5842)