RocketChat/Rocket.Chat · error · MeteorError
error-code-invalid
error-code-invalid
Error message
Invalid code
What it means
The join-code branch of join() validates the supplied code with Rooms.findOneByJoinCodeAndId(joinCode, room._id); if no room matches, the code is wrong for this room and join throws Meteor error-code-invalid ('Invalid code', method 'joinRoom').
Source
Thrown at apps/meteor/server/services/room/service.ts:215
if (
FederationActions.shouldPerformFederationAction(room) &&
!isUserNativeFederated(user) &&
!(await FederationMatrix.canUserAccessFederation(user))
) {
throw new MeteorError('error-not-authorized-federation', 'Not authorized to access federation', { method: 'joinRoom' });
}
if (isRoomWithJoinCode(room) && !(await Authorization.hasPermission(user._id, 'join-without-join-code'))) {
if (!joinCode) {
throw new MeteorError('error-code-required', 'Code required', { method: 'joinRoom' });
}
const isCorrectJoinCode = !!(await Rooms.findOneByJoinCodeAndId(joinCode, room._id, {
projection: { _id: 1 },
}));
if (!isCorrectJoinCode) {
throw new MeteorError('error-code-invalid', 'Invalid code', { method: 'joinRoom' });
}
}
return addUserToRoom(room._id, user);
}
async beforeLeave(room: IRoom): Promise<void> {
FederationActions.blockIfRoomFederatedButServiceNotReady(room);
}
async beforeUserRemoved(room: IRoom): Promise<void> {
FederationActions.blockIfRoomFederatedButServiceNotReady(room);
}
async beforeNameChange(room: IRoom): Promise<void> {
FederationActions.blockIfRoomFederatedButServiceNotReady(room);
}
View on GitHub (pinned to b2c16d5842)
Solutions
- Trim/verify the input and re-check the code with the room owner, then re-submit exactly
- Owners can reset the room's join code and re-share it
- Grant join-without-join-code to trusted roles to avoid code handling entirely
Example fix
// before
await roomService.join({ room, user, joinCode: codeFromUser });
// after
const joinCode = codeFromUser?.trim();
if (!joinCode) throw new Error('error-code-required');
await roomService.join({ room, user, joinCode }); Defensive patterns
Strategy: try-catch
Validate before calling
const joinCode = rawInput?.trim();
if (!joinCode) throw new Error('error-code-required');
const matches = await Rooms.findOneByJoinCodeAndId(joinCode, room._id, { projections: { _id: 1 } });
if (!matches) {
// wrong code: re-prompt instead of calling join() and failing
return rePromptForJoinCode(room);
} Type guard
const isValidJoinCode = async (joinCode: string, roomId: string): Promise<boolean> =>
Boolean(await Rooms.findOneByJoinCodeAndId(joinCode.trim(), roomId, { projections: { _id: 1 } })); Try / catch
try {
await roomService.join({ room, user, joinCode });
} catch (err) {
if (err?.error === 'error-code-invalid') {
// re-prompt with a fresh attempt limit; do not auto-retry the same code
return rePromptForJoinCode(room);
}
throw err;
} Prevention
- Trim join-code input before submitting
- Ask owners to re-share the code after rotations instead of brute-forcing retries
- Reset the room's join code when it is suspected compromised rather than chasing mismatches
When it happens
Trigger: Submitting an incorrect or outdated join code for a join-code-protected room: typos, codes rotated by owners, or copy/paste artifacts (extra whitespace).
Common situations: Owners changed the code after it was shared; users pasting codes with trailing spaces; case mismatches.
Related errors
- error-code-required
- error-not-allowed
- room-closed
- error-not-authorized-federation
- error-invalid-subscription
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/2c08a2a101d49e7a.
Report an issue: GitHub.