RocketChat/Rocket.Chat · error

A video conference must exist to update.

Error message

A video conference must exist to update.

What it means

The video-conferences bridge update path loads the existing call via VideoConf.getUnfiltered(call._id); when that returns nothing — the id is absent or no such call exists — it throws 'A video conference must exist to update.'. Updates are patches over an existing call record; there is no upsert here (creation goes through the separate create path).

Solutions

  1. Fetch the current call via the video-conference reader (getById) and update that fetched object.
  2. If no call exists yet, create it through the create path first, then update.
  3. Treat this error as 'call ended or removed' and stop tracking that call id.

Example fix

// before
await updateVideoConference(locallyBuiltCall, appId); // _id unset or unknown

// after
const call = await this.read.getVideoConferenceReader().getById(callId);
if (!call) {
  return; // nothing to update; call does not exist
}
await updateVideoConference({ ...call, status }, appId);
Defensive patterns

Strategy: validation

Validate before calling

const call = await this.read.getVideoConferenceReader().getById(callId);
if (!call) {
  return; // call does not exist; nothing to update
}

Type guard

const isExistingCall = (c: VideoConference | undefined | null): c is VideoConference & { _id: string } =>
  Boolean(c && c._id);

Try / catch

Catch and treat as 'call ended/removed': stop tracking the call id and clean up associated state.

Prevention

When it happens

Trigger: App calls update with a VideoConference object whose _id is undefined or references a call that was never created through the provider flow; updating a call id from another deployment; updating after the call record was removed.

Common situations: Apps constructing a VideoConference object locally instead of fetching the live one; storing call refs across restarts; racing with call teardown/cleanup.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at apps/meteor/app/apps/server/bridges/videoConferences.ts:39

	}

	protected async create(call: AppVideoConference, appId: string): Promise<string> {
		this.orch.debugLog(`The App ${appId} is creating a video conference.`);

		return (
			await VideoConf.create({
				type: 'videoconference',
				...call,
			})
		).callId;
	}

	protected async update(call: VideoConference, appId: string): Promise<void> {
		this.orch.debugLog(`The App ${appId} is updating a video conference.`);

		const oldData = call._id && (await VideoConf.getUnfiltered(call._id));
		if (!oldData) {
			throw new Error('A video conference must exist to update.');
		}

		const data = (this.orch.getConverters()?.get('videoConferences') as AppVideoConferencesConverter).convertAppVideoConference(call);
		await VideoConf.setProviderData(call._id, data.providerData);

		for (const { _id, ts } of data.users) {
			if (oldData.users.find((user) => user._id === _id)) {
				continue;
			}

			await VideoConf.addUser(call._id, _id, ts);
		}

		if (data.endedBy && data.endedBy._id !== oldData.endedBy?._id) {
			await VideoConf.setEndedBy(call._id, data.endedBy._id);
		} else if (data.endedAt) {
			await VideoConf.setEndedAt(call._id, data.endedAt);
		}

View on GitHub (pinned to b2c16d5842)