{"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":"Error","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/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/app/apps/server/bridges/videoConferences.ts#L21-L57","documentation":"Thrown by the video conferences bridge update method when no existing video conference matches the provided call._id (or when _id is absent so the lookup is skipped). Update is a mutation on an existing record; the bridge loads the prior state via VideoConf.getUnfiltered and refuses to proceed if there is nothing to mutate.","triggerScenarios":"App calls update with a call object whose _id is undefined, refers to a conference that was never created, or to one that has been deleted. The check is `const oldData = call._id && (await VideoConf.getUnfiltered(call._id)); if (!oldData) throw ...`.","commonSituations":"App updates a conference from a stale/cached object whose id no longer exists; conference ended and was cleaned up before the update; _id field stripped during serialization; race between create and update.","solutions":["Ensure the video conference was created (create returned a callId) before calling update.","Pass the exact callId returned by create as call._id.","Re-fetch the conference before updating to confirm it still exists."],"exampleFix":"// before\nawait videoConf.update({ ...staleCall, status: 'ended' });\n\n// after\nconst existing = await VideoConf.getUnfiltered(callId);\nif (!existing) {\n  // conference already gone; nothing to update\n  return;\n}\nawait videoConf.update({ ...existing, status: 'ended' });","handlingStrategy":"validation","validationCode":"if (!call._id) {\n  throw new Error('Cannot update video conference: missing _id');\n}\nconst existing = await VideoConf.getUnfiltered(call._id);\nif (!existing) {\n  throw new Error('Cannot update video conference: not found');\n}","typeGuard":"function hasExistingCallId(call: VideoConference): call is VideoConference & { _id: string } {\n  return typeof call._id === 'string' && call._id.length > 0;\n}","tryCatchPattern":"try {\n  await videoConf.update(call);\n} catch (err) {\n  if (err instanceof Error && err.message === 'A video conference must exist to update.') {\n    // conference was deleted; create a new one instead\n  } else {\n    throw err;\n  }\n}","preventionTips":["Always pass the callId returned by create as call._id.","Re-fetch the conference before updating to confirm it still exists.","Handle create-then-update races by re-creating if missing."],"tags":["apps-engine","video-conference","validation","not-found"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}