{"record":{"id":"c9676ddb5a1e076e","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-shortcut","errorCode":"error-invalid-shortcut","errorMessage":"Shortcut provided already exists","messagePattern":"Shortcut provided already exists","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/ee/server/meteor-methods/saveCannedResponse.ts","lineNumber":61,"sourceCode":"\tconst canSaveDepartment = await hasPermissionAsync(userId, 'save-department-canned-responses');\n\tif (!canSaveAll && !canSaveDepartment && ['department'].includes(responseData.scope)) {\n\t\tthrow new Meteor.Error('error-not-allowed', 'Not allowed to modify canned responses on *department* scope', {\n\t\t\tmethod: 'saveCannedResponse',\n\t\t});\n\t}\n\n\t// to avoid inconsistencies\n\tif (responseData.scope === 'user') {\n\t\tdelete responseData.departmentId;\n\t}\n\t// TODO: check if the department i'm trying to save is a department i can interact with\n\n\t// check if the response already exists and we're not updating one\n\tconst duplicateShortcut = await CannedResponse.findOneByShortcut(responseData.shortcut, {\n\t\tprojection: { _id: 1 },\n\t});\n\tif ((!_id && duplicateShortcut) || (_id && duplicateShortcut && duplicateShortcut._id !== _id)) {\n\t\tthrow new Meteor.Error('error-invalid-shortcut', 'Shortcut provided already exists', {\n\t\t\tmethod: 'saveCannedResponse',\n\t\t});\n\t}\n\n\tif (responseData.scope === 'department' && !responseData.departmentId) {\n\t\tthrow new Meteor.Error('error-invalid-department', 'Invalid department', {\n\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}","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/ee/server/meteor-methods/saveCannedResponse.ts#L43-L79","documentation":"Thrown by saveCannedResponse when a canned response with the same shortcut already exists and would collide. Collision is detected via CannedResponse.findOneByShortcut: it fires on a create with no _id where the shortcut exists, or on an update (_id set) where a different document owns the shortcut. Code is 'error-invalid-shortcut'.","triggerScenarios":"Creating a new canned response with a shortcut already in use; renaming an existing response to a shortcut owned by another response.","commonSituations":"User picks a shortcut like '/hi' that is already taken; import/seed data introduces duplicate shortcuts; UI does not check uniqueness inline before submit.","solutions":["Check shortcut uniqueness via CannedResponse.findOneByShortcut before submit and warn the user.","Enforce unique shortcut input in the UI (debounced availability check).","On collision, prompt the user to pick a different shortcut or update the existing response instead."],"exampleFix":"// before\nawait saveCannedResponse(userId, responseData, _id);\n\n// after\nconst dup = await CannedResponse.findOneByShortcut(responseData.shortcut, { projection: { _id: 1 } });\nif (dup && dup._id !== _id) {\n  throw new Error('Shortcut already in use');\n}\nawait saveCannedResponse(userId, responseData, _id);","handlingStrategy":"validation","validationCode":"const dup = await CannedResponse.findOneByShortcut(responseData.shortcut, { projection: { _id: 1 } });\nif (dup && dup._id !== _id) {\n  throw new Error('Shortcut already in use');\n}\nawait saveCannedResponse(userId, responseData, _id);","typeGuard":"function isShortcutValid(shortcut: string): boolean {\n  return /^[a-z0-9-_]{1,32}$/i.test(shortcut);\n}","tryCatchPattern":"try {\n  await saveCannedResponse(userId, responseData, _id);\n} catch (e) {\n  if (isMeteorError(e, 'error-invalid-shortcut')) {\n    notifyUser(`The shortcut \"${responseData.shortcut}\" is already taken.`);\n    return;\n  }\n  throw e;\n}","preventionTips":["Run a debounced shortcut-availability check in the UI before submit.","Validate shortcut format/length before uniqueness lookup.","On collision, prompt to rename or update the existing response."],"tags":["canned-responses","uniqueness","validation","shortcut"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}