RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-room
error-invalid-room
Error message
Invalid room
What it means
unarchiveRoom loads the room with Rooms.findOneById(rid); a null result throws error-invalid-room. The id must identify an existing room document in the connected database before any unarchive logic runs.
Source
Thrown at apps/meteor/server/meteor-methods/rooms/unarchiveRoom.ts:29
declare module '@rocket.chat/ddp-client' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
unarchiveRoom(rid: string): Promise<void>;
}
}
export const executeUnarchiveRoom = async (userId: string, rid: string) => {
check(rid, String);
const user = await Users.findOneById(userId, { projection: { username: 1, name: 1 } });
if (!user || !isRegisterUser(user)) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'archiveRoom' });
}
const room = await Rooms.findOneById(rid);
if (!room) {
throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'unarchiveRoom' });
}
if (!(await hasPermissionAsync(userId, 'unarchive-room', room._id))) {
throw new Meteor.Error('error-not-authorized', 'Not authorized', { method: 'unarchiveRoom' });
}
return unarchiveRoom(rid, user);
};
Meteor.methods<ServerMethods>({
async unarchiveRoom(rid) {
methodDeprecationLogger.method('unarchiveRoom', '9.0.0', '/v1/channels.unarchive');
const userId = Meteor.userId();
if (!userId) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'unarchiveRoom' });
}
View on GitHub (pinned to b2c16d5842)
Solutions
- Confirm the room exists (Rooms.findOneById, or REST rooms.info) before unarchiving
- If the room was deleted rather than archived, restore it from trash/backup instead of calling unarchive
- Check the id source and the connected database when ids systematically fail to resolve
- Verify the room is actually archived — unarchive is only meaningful for archived rooms
Example fix
// before
await executeUnarchiveRoom(userId, rid); // rid no longer exists
// after
const room = await Rooms.findOneById(rid, { projection: { _id: 1, archived: 1 } });
if (!room) throw new Meteor.Error('error-invalid-room', 'Invalid room');
await executeUnarchiveRoom(userId, room._id); Defensive patterns
Strategy: validation
Validate before calling
const room = await Rooms.findOneById(rid, { projection: { _id: 1, archived: 1 } });
if (!room) {
// rid does not resolve: refresh it or stop before calling unarchiveRoom
} Try / catch
try {
await Meteor.callAsync('unarchiveRoom', rid);
} catch (error) {
if (error instanceof Meteor.Error && error.error === 'error-invalid-room') {
// room gone: clear stale state; if it was deleted (not archived) restore via trash/backup
}
} Prevention
- Resolve rooms by id right before acting on them; do not cache rids across sessions
- Distinguish archived rooms (unarchive works) from deleted rooms (restore path)
- Verify environment/database when ids stop resolving
When it happens
Trigger: Calling unarchiveRoom with the id of a deleted room, an id from another workspace or environment, or a malformed/truncated id string.
Common situations: Attempting to restore a room that was permanently removed instead of archived; stale rid in admin tooling; connected to the wrong database after a migration.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/8da44f012b05813b.
Report an issue: GitHub.