RocketChat/Rocket.Chat · error · Meteor.Error
error-token-does-not-exists
error-token-does-not-exists
Error message
Token does not exist
What it means
Thrown by regeneratePersonalAccessTokenOfUser when Users.findPersonalAccessTokenByTokenNameAndUserId returns null — there is no personal access token with that name for the user. Regeneration requires an existing token to replace, so a missing token is an error rather than a create.
Source
Thrown at apps/meteor/imports/personal-access-tokens/server/api/methods/regenerateToken.ts:29
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
'personalAccessTokens:regenerateToken'(params: { tokenName: string }): Promise<string>;
}
}
export const regeneratePersonalAccessTokenOfUser = async (tokenName: string, userId: string): Promise<string> => {
if (!(await hasPermissionAsync(userId, 'create-personal-access-tokens'))) {
throw new Meteor.Error('not-authorized', 'Not Authorized', {
method: 'personalAccessTokens:regenerateToken',
});
}
const tokenExist = await Users.findPersonalAccessTokenByTokenNameAndUserId({
userId,
tokenName,
});
if (!tokenExist) {
throw new Meteor.Error('error-token-does-not-exists', 'Token does not exist', {
method: 'personalAccessTokens:regenerateToken',
});
}
await removePersonalAccessTokenOfUser(tokenName, userId);
const tokenObject = tokenExist.services?.resume?.loginTokens?.find((token) => isPersonalAccessToken(token) && token.name === tokenName);
return generatePersonalAccessTokenOfUser({
tokenName,
userId,
bypassTwoFactor: (tokenObject && isPersonalAccessToken(tokenObject) && tokenObject.bypassTwoFactor) || false,
});
};
Meteor.methods<ServerMethods>({
'personalAccessTokens:regenerateToken': twoFactorRequired(async function ({ tokenName }: { tokenName: string }) {
const uid = Meteor.userId();View on GitHub (pinned to f9d3ec372b)
Solutions
- If you want a brand-new token, call generateToken instead of regenerateToken.
- Re-fetch the user's token list and use the exact existing name.
- Confirm the token still exists before offering a 'regenerate' action in the UI.
- Handle the error by prompting the user to create a new token.
Example fix
// before
await regeneratePersonalAccessTokenOfUser('typo-name', userId);
// after
const exists = await Users.findPersonalAccessTokenByTokenNameAndUserId({ userId, tokenName });
if (!exists) {
await generatePersonalAccessTokenOfUser({ userId, tokenName, bypassTwoFactor: false });
} else {
await regeneratePersonalAccessTokenOfUser(tokenName, userId);
} Defensive patterns
Strategy: validation
Validate before calling
async function tokenExists(userId: string, tokenName: string): Promise<boolean> {
const t = await Users.findPersonalAccessTokenByTokenNameAndUserId({ userId, tokenName });
return Boolean(t);
} Try / catch
try {
await regeneratePersonalAccessTokenOfUser(tokenName, userId);
} catch (e) {
if (e.error === 'error-token-does-not-exists') {
// fall back to generateToken
await generatePersonalAccessTokenOfUser({ userId, tokenName, bypassTwoFactor: false });
} else throw e;
} Prevention
- Only offer 'regenerate' for tokens that currently exist (live list).
- Use exact tokenName spelling/case.
- Fall back to generate when the named token is gone.
When it happens
Trigger: Calling regenerateToken with a tokenName the user never created, that was already removed, or whose name does not exactly match.
Common situations: Token was deleted by another admin or in another tab; typo in tokenName; UI showed a stale token list after deletion; case mismatch in the name.
Related errors
- error-token-does-not-exists
- Room id not found
- A video conference must exist to update.
- error-canned-response-not-found
- error-token-already-exists
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/6a9fc9ff3a15d48f.
Report an issue: GitHub.