{"record":{"id":"343afb98ee142483","repo":"RocketChat/Rocket.Chat","slug":"error-canned-response-not-found-343afb","errorCode":"error-canned-response-not-found","errorMessage":"Canned Response not found","messagePattern":"Canned Response not found","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/ee/server/meteor-methods/saveCannedResponse.ts","lineNumber":86,"sourceCode":"\t\t\tmethod: 'saveCannedResponse',\n\t\t});\n\t}\n\n\tif (\n\t\tresponseData.departmentId &&\n\t\t!(await LivechatDepartment.findOneById<Pick<ILivechatDepartment, '_id'>>(responseData.departmentId, { projection: { _id: 1 } }))\n\t) {\n\t\tthrow new Meteor.Error('error-invalid-department', 'Invalid department', {\n\t\t\tmethod: 'saveCannedResponse',\n\t\t});\n\t}\n\n\tlet result: Omit<IOmnichannelCannedResponse, '_updatedAt' | '_createdAt'> & { _createdAt?: Date };\n\n\tif (_id) {\n\t\tconst cannedResponse = await CannedResponse.findOneById(_id);\n\t\tif (!cannedResponse) {\n\t\t\tthrow new Meteor.Error('error-canned-response-not-found', 'Canned Response not found', {\n\t\t\t\tmethod: 'saveCannedResponse',\n\t\t\t});\n\t\t}\n\n\t\tresult = await CannedResponse.updateCannedResponse(_id, {\n\t\t\t...responseData,\n\t\t\t...(cannedResponse.scope === 'user' && { userId: cannedResponse.userId }),\n\t\t\tcreatedBy: cannedResponse.createdBy,\n\t\t});\n\t} else {\n\t\tconst user = await Users.findOneById(userId);\n\n\t\tconst data = {\n\t\t\t...responseData,\n\t\t\t...(responseData.scope === 'user' && { userId: user?._id }),\n\t\t\tcreatedBy: { _id: user?._id || '', username: user?.username || '' },\n\t\t\t_createdAt: new Date(),\n\t\t};","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/ee/server/meteor-methods/saveCannedResponse.ts#L68-L104","documentation":"Thrown by saveCannedResponse when an _id is passed (indicating an update) but CannedResponse.findOneById(_id) returns null. The method cannot update a canned response that does not exist, so it aborts. This guards against updating a record that was deleted between the client loading it and submitting the edit.","triggerScenarios":"Calling saveCannedResponse with a third _id argument that does not match any document in the canned_responses collection; editing a canned response in one tab while another tab/admin deletes it.","commonSituations":"Stale _id held in client state after deletion; concurrent admin sessions; restoring from an old backup of the front-end cache; test fixtures that reference a non-inserted id.","solutions":["If the record was deleted, switch to the create flow (omit _id) instead of update.","Re-fetch the canned response by _id before showing the edit form; disable submit if it is gone.","On catching this error, reload the canned-response list in the UI and have the user re-open the item.","Verify the _id string is correct and from the same workspace."],"exampleFix":"// before\nawait saveCannedResponse(userId, data, staleId);\n\n// after\nconst existing = await CannedResponse.findOneById(staleId);\nif (!existing) {\n  await saveCannedResponse(userId, data); // create instead\n} else {\n  await saveCannedResponse(userId, data, staleId);\n}","handlingStrategy":"validation","validationCode":"async function cannedResponseExists(_id: string): Promise<boolean> {\n  const existing = await CannedResponse.findOneById(_id, { projection: { _id: 1 } });\n  return Boolean(existing);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await saveCannedResponse(userId, data, _id);\n} catch (e) {\n  if (e.error === 'error-canned-response-not-found') {\n    // fall back to create flow\n    await saveCannedResponse(userId, data);\n  } else throw e;\n}","preventionTips":["Re-fetch the canned response by _id before opening the edit form.","Disable submit if the underlying record disappears (use a live subscription).","Handle concurrent deletes gracefully by falling back to create."],"tags":["omnichannel","canned-response","not-found","concurrency"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}