RocketChat/Rocket.Chat · error · Error

invalid-call-target

Error message

invalid-call-target

What it means

Thrown by startDirect() when computing the callee: uids.filter(uid => uid !== user._id).pop() is empty, i.e. the direct-message room contains no member other than the caller. The source comment spells out the main case: 'Are you trying to call yourself?'. A DM with only yourself (self/notes room) or a room document with missing/empty uids cannot be a direct call target.

Source

Thrown at apps/meteor/server/services/video-conference/service.ts:739

		const subscriptions = Subscriptions.findByRoomIdAndNotUserId(call.rid, call.createdBy._id, {
			projection: { 'u._id': 1, '_id': 0 },
		});

		for await (const subscription of subscriptions) {
			await this.sendPushNotification(call, subscription.u._id);
		}
	}

	private async startDirect(
		providerName: string,
		user: IUser,
		{ _id: rid, uids }: AtLeast<IRoom, '_id' | 'uids'>,
		extraData?: Partial<IDirectVideoConference>,
	): Promise<DirectCallInstructions> {
		const calleeId = uids?.filter((uid) => uid !== user._id).pop();
		if (!calleeId) {
			// Are you trying to call yourself?
			throw new Error('invalid-call-target');
		}

		const callId = await VideoConferenceModel.createDirect({
			...extraData,
			rid,
			createdBy: {
				_id: user._id,
				name: user.name as string,
				username: user.username as string,
			},
			providerName,
		});

		await this.runNewVideoConferenceEvent(callId);

		await this.maybeCreateDiscussion(callId, user);

		const call = (await this.getUnfiltered(callId)) as IDirectVideoConference | null;

View on GitHub (pinned to e4b8178b20)

Solutions

  1. Start the call from a DM with exactly one other member instead of a self-chat
  2. If building an integration or custom client, verify the room type and that uids contains another user before invoking start
  3. Repair room documents whose uids array is missing or malformed (audit the rooms collection)
  4. Hide the call button for self-chats in custom clients (stock clients already do)

Example fix

// before
await videoConfService.startCall(user, { _id: rid, uids }); // may throw 'invalid-call-target'

// after
const calleeId = uids?.filter((uid) => uid !== user._id).pop();
if (!calleeId) {
	return refuse('Cannot start a direct call in a room with no other member');
}
await videoConfService.startCall(user, { _id: rid, uids });
Defensive patterns

Strategy: validation

Validate before calling

const calleeId = room.uids?.filter((uid) => uid !== user._id).pop();
if (!calleeId) {
	return notifyUser('Cannot start a call in a room without another member');
}
await videoConfService.startCall(user, { _id: room._id, uids: room.uids });

Type guard

const hasCallTarget = (room: { uids?: string[] }, uid: string): boolean =>
	Boolean(room.uids?.filter((u) => u !== uid).pop());

Try / catch

catch (err) { if (err instanceof Error && err.message === 'invalid-call-target') { /* tell the caller this room has no other member */ } else throw err; }

Prevention

When it happens

Trigger: Starting a video call in a self-chat / 'save messages' room (uids === [callerId]); starting a call on a room whose uids array is undefined or lacks a second user (corrupted or hand-crafted room doc); calling startCall with an rid that resolves to such a room.

Common situations: Users clicking the call button in their own notes/self conversation; imported or migrated rooms with incomplete uids; automation or test code reusing the rid of a self-room.

Related errors


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