{"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/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/ee/server/meteor-methods/saveCannedResponse.ts#L68-L104","documentation":"saveCannedResponse (saveCannedResponse.ts:86) takes the update path when _id is provided; if CannedResponse.findOneById(_id) returns null (the record was deleted after the editor loaded it), it throws error-canned-response-not-found instead of upserting.","triggerScenarios":"Updating a canned response that no longer exists — another user/session deleted it while the editor form was open, or the _id is stale/wrong.","commonSituations":"Two agents editing the same canned response and one deleting it; list not refreshed after a deletion; retrying a save after the record was removed by an admin cleanup.","solutions":["Refresh the canned responses list; if the record is gone, create it again instead of updating","Handle error-canned-response-not-found in the editor by warning the user the item was deleted","Pre-check existence before saving when the editing session is long-lived"],"exampleFix":"// before\nawait saveCannedResponse(uid, responseData, _id);\n\n// after\nconst existing = _id ? await CannedResponse.findOneById(_id, { projection: { _id: 1 } }) : null;\nif (_id && !existing) {\n\t// record deleted meanwhile — fall back to create\n\treturn saveCannedResponse(uid, responseData);\n}\nawait saveCannedResponse(uid, responseData, _id);","handlingStrategy":"validation","validationCode":"if (_id) {\n\tconst existing = await CannedResponse.findOneById(_id, { projection: { _id: 1 } });\n\tif (!existing) {\n\t\t// record deleted meanwhile — create instead of update\n\t\treturn saveCannedResponse(userId, responseData);\n\t}\n}\nawait saveCannedResponse(userId, responseData, _id);","typeGuard":null,"tryCatchPattern":"try {\n\tawait saveCannedResponse(userId, responseData, _id);\n} catch (e) {\n\tif (e instanceof Meteor.Error && e.error === 'error-canned-response-not-found') {\n\t\t// refresh the list and re-open; the record was deleted by someone else\n\t}\n\tthrow e;\n}","preventionTips":["Re-check existence before saving long-lived editor forms","Surface deletion notices to concurrent editors (canned-responses stream emits 'removed')","Treat update-on-deleted as a create-or-abort decision, never a blind retry"],"tags":["canned-responses","not-found","omnichannel","concurrent-edit"],"backgroundTag":"resource-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"}