{"record":{"id":"a40a519ebebef4f2","repo":"RocketChat/Rocket.Chat","slug":"a-video-conference-must-exist-to-update","errorCode":null,"errorMessage":"A video conference must exist to update.","messagePattern":"A video conference must exist to update\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/meteor/app/apps/server/bridges/videoConferences.ts","lineNumber":39,"sourceCode":"\t}\n\n\tprotected async create(call: AppVideoConference, appId: string): Promise<string> {\n\t\tthis.orch.debugLog(`The App ${appId} is creating a video conference.`);\n\n\t\treturn (\n\t\t\tawait VideoConf.create({\n\t\t\t\ttype: 'videoconference',\n\t\t\t\t...call,\n\t\t\t})\n\t\t).callId;\n\t}\n\n\tprotected async update(call: VideoConference, appId: string): Promise<void> {\n\t\tthis.orch.debugLog(`The App ${appId} is updating a video conference.`);\n\n\t\tconst oldData = call._id && (await VideoConf.getUnfiltered(call._id));\n\t\tif (!oldData) {\n\t\t\tthrow new Error('A video conference must exist to update.');\n\t\t}\n\n\t\tconst data = (this.orch.getConverters()?.get('videoConferences') as AppVideoConferencesConverter).convertAppVideoConference(call);\n\t\tawait VideoConf.setProviderData(call._id, data.providerData);\n\n\t\tfor (const { _id, ts } of data.users) {\n\t\t\tif (oldData.users.find((user) => user._id === _id)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tawait VideoConf.addUser(call._id, _id, ts);\n\t\t}\n\n\t\tif (data.endedBy && data.endedBy._id !== oldData.endedBy?._id) {\n\t\t\tawait VideoConf.setEndedBy(call._id, data.endedBy._id);\n\t\t} else if (data.endedAt) {\n\t\t\tawait VideoConf.setEndedAt(call._id, data.endedAt);\n\t\t}","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/app/apps/server/bridges/videoConferences.ts#L21-L57","documentation":"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).","triggerScenarios":"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.","commonSituations":"Apps constructing a VideoConference object locally instead of fetching the live one; storing call refs across restarts; racing with call teardown/cleanup.","solutions":["Fetch the current call via the video-conference reader (getById) and update that fetched object.","If no call exists yet, create it through the create path first, then update.","Treat this error as 'call ended or removed' and stop tracking that call id."],"exampleFix":"// before\nawait updateVideoConference(locallyBuiltCall, appId); // _id unset or unknown\n\n// after\nconst call = await this.read.getVideoConferenceReader().getById(callId);\nif (!call) {\n  return; // nothing to update; call does not exist\n}\nawait updateVideoConference({ ...call, status }, appId);","handlingStrategy":"validation","validationCode":"const call = await this.read.getVideoConferenceReader().getById(callId);\nif (!call) {\n  return; // call does not exist; nothing to update\n}","typeGuard":"const isExistingCall = (c: VideoConference | undefined | null): c is VideoConference & { _id: string } =>\n  Boolean(c && c._id);","tryCatchPattern":"Catch and treat as 'call ended/removed': stop tracking the call id and clean up associated state.","preventionTips":["Update only call objects fetched from the video-conference reader.","Create calls through the provider flow before updating them.","Re-validate stored call ids after restarts and long-running sessions."],"tags":["apps-engine","video-conference","not-found"],"backgroundTag":"record-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}