{"record":{"id":"7230480182c3a851","repo":"RocketChat/Rocket.Chat","slug":"error-duplicate-priority-name","errorCode":"error-duplicate-priority-name","errorMessage":"error-duplicate-priority-name","messagePattern":"error-duplicate-priority-name","errorType":"exception","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/ee/server/api/v1/omnichannel/lib/priorities.ts","lineNumber":49,"sourceCode":"\t\tlimit: count,\n\t});\n\n\tconst [priorities, total] = await Promise.all([cursor.toArray(), totalCount]);\n\n\treturn {\n\t\tpriorities,\n\t\tcount: priorities.length,\n\t\toffset,\n\t\ttotal,\n\t};\n}\n\nexport async function updatePriority(_id: string, data: Pick<ILivechatPriority, 'name'> & { reset?: boolean }): Promise<ILivechatPriority> {\n\tif (data.name) {\n\t\t// If we want to enforce translated duplicates we need to change this\n\t\tconst priority = await LivechatPriority.findOneNameUsingRegex(data.name, { projection: { name: 1 } });\n\t\tif (priority && priority._id !== _id) {\n\t\t\tthrow new Error('error-duplicate-priority-name');\n\t\t}\n\t}\n\n\tconst createdResult = await LivechatPriority.updatePriority(_id, data.reset || false, data.name);\n\n\tif (!createdResult) {\n\t\tlogger.error({ msg: 'Error updating priority: unsuccessful result from MongoDB', priorityId: _id, result: createdResult });\n\t\tthrow Error('error-unable-to-update-priority');\n\t}\n\n\treturn createdResult;\n}\n\nexport const updateRoomPriority = async (\n\trid: string,\n\tuser: Required<Pick<IUser, '_id' | 'username' | 'name'>>,\n\tpriorityId: string,\n): Promise<void> => {","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/ee/server/api/v1/omnichannel/lib/priorities.ts#L31-L67","documentation":"Thrown by updatePriority (reached via PUT livechat/priorities/:priorityId) when the requested name already belongs to a different LivechatPriority. The check uses LivechatPriority.findOneNameUsingRegex, so the match is regex-based and effectively case-insensitive; a name whose regex metacharacters match another priority can also trip it. The source comment notes translated duplicates are deliberately not enforced. The MongoDB update never runs when this fires.","triggerScenarios":"PUT /api/v1/livechat/priorities/:priorityId with body {\"name\": \"high\"} while another priority is already named \"High\"; or a name containing regex metacharacters (e.g. \"Hi.g\", \"Urgent*\") whose pattern matches an existing priority name. Also fires when renaming priority A to B's name without renaming B first.","commonSituations":"Renaming priorities to canonical names (High/Urgent) that already exist; API seeding scripts where only casing differs; names pasted from chat that contain dots, asterisks, or brackets; swapping two priority names in the wrong order.","solutions":["Choose a name no other priority uses, accounting for case-insensitive matching (list them with GET /api/v1/livechat/priorities first).","If swapping names, rename the existing priority to a temporary name before assigning its name to the target.","If the duplicate report looks false, remove regex metacharacters such as . * + ? [ ] ( ) | from the name and retry, since the lookup is regex-based.","Send {\"reset\": true} instead of a name if you only want to restore that priority's default name."],"exampleFix":"// before\nawait api.put(`/v1/livechat/priorities/${priorityId}`, { name: 'high' });\n// -> error-duplicate-priority-name: a priority named \"High\" already exists\n\n// after\nconst { priorities } = await api.get('/v1/livechat/priorities', { params: { count: 0 } });\nconst taken = priorities.some((p) => p._id !== priorityId && p.name.toLowerCase() === 'high');\nawait api.put(`/v1/livechat/priorities/${priorityId}`, { name: taken ? 'High - Tier 2' : 'high' });","handlingStrategy":"validation","validationCode":"const { priorities } = await api.get('/v1/livechat/priorities', { params: { count: 0 } });\nconst conflict = priorities.some(\n  (p) => p._id !== priorityId && p.name.toLowerCase() === newName.toLowerCase(),\n);\nif (conflict) throw new Error(`Priority name \"${newName}\" is already in use`);\nawait api.put(`/v1/livechat/priorities/${priorityId}`, { name: newName });","typeGuard":null,"tryCatchPattern":"try {\n  await api.put(`/v1/livechat/priorities/${priorityId}`, { name });\n} catch (e) {\n  if (e?.response?.data?.errorType === 'error-duplicate-priority-name') {\n    // prompt the user for another name; do NOT retry with the same value\n  } else throw e;\n}","preventionTips":["Treat priority names as unique case-insensitive keys; check the list endpoint before every rename.","Keep regex metacharacters out of priority names.","When swapping two names, rename via a temporary name first."],"tags":["omnichannel","livechat-priorities","duplicate-name","regex-matching","rest-api"],"backgroundTag":"unique-constraint-violation","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}