RocketChat/Rocket.Chat · error · Meteor.Error

invalid-channel

invalid-channel

Error message

invalid-channel

What it means

BotHelpers.addUserToRoom resolves its `room` argument via Rooms.findOneByIdOrName and throws a bare 'invalid-channel' Meteor.Error when nothing matches either a room _id or a room name. It is reached through the DDP method 'botRequest' (restricted to authenticated users holding the 'bot' role) and is the surface hubot-style bots use to add users to rooms.

Source

Thrown at apps/meteor/server/lib/bot-helpers/index.ts:78

			return p(...params);
		}

		return p;
	}

	async addUserToRole(userName: string, roleId: string, userId: string): Promise<void> {
		await addUserToRole(userId, roleId, userName);
	}

	async removeUserFromRole(userName: string, roleId: string, userId: string): Promise<void> {
		await removeUserFromRole(userId, roleId, userName);
	}

	async addUserToRoom(userName: string, room: string): Promise<void> {
		const foundRoom = await Rooms.findOneByIdOrName(room);

		if (!foundRoom) {
			throw new Meteor.Error('invalid-channel');
		}

		const userId = Meteor.userId();
		if (!userId) {
			throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'addUserToRoom' });
		}
		await addUsersToRoomMethod(userId, {
			rid: foundRoom._id,
			users: [userName],
		});
	}

	async removeUserFromRoom(userName: string, room: string) {
		const foundRoom = await Rooms.findOneByIdOrName(room);

		if (!foundRoom) {
			throw new Meteor.Error('invalid-channel');
		}

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Resolve the room first via rooms.info (by roomId or roomName) and pass the canonical name or _id
  2. Strip '#', '@', and whitespace decorations from user-supplied names before calling
  3. Keep bot-usable room names in configuration and validate them at bot startup

Example fix

// before
await call('botRequest', 'addUserToRoom', 'alice', '#general'); // invalid-channel

// after
const room = await GET '/api/v1/rooms.info' { roomName: 'general' };
await call('botRequest', 'addUserToRoom', 'alice', room.room._id);
Defensive patterns

Strategy: validation

Validate before calling

const { room } = await GET '/api/v1/rooms.info' { roomName: room.replace(/^#/, '') };
// fall back to { roomId } lookup if name lookup fails
if (!room) {
  // do not call botRequest addUserToRoom with an unresolvable room
}

Type guard

const isRoomRef = (room: unknown): room is { _id: string; name: string } =>
  typeof room === 'object' && room !== null && '_id' in room && 'name' in room;

Try / catch

try {
  await call('botRequest', 'addUserToRoom', username, roomRef);
} catch (e) {
  if (e instanceof Meteor.Error && e.error === 'invalid-channel') {
    // re-resolve the room by id/name and retry once
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: The bot passes a room name with a leading '#', a typo, or wrong case expectations; the room was deleted or renamed; passing the room's display name (fname) that differs from the stored name; passing a topic/description instead of the name.

Common situations: Hubot scripts hardcoding channel names that drift over time; multi-lingual workspaces where display names differ from stored names; bots restored onto a fresh workspace without their old channels.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/86bc157e3a2b053c. Report an issue: GitHub.