{"record":{"id":"f422b91cc001260e","repo":"RocketChat/Rocket.Chat","slug":"custom-user-status-error-invalid-user-status","errorCode":"Custom_User_Status_Error_Invalid_User_Status","errorMessage":"Invalid user status","messagePattern":"Invalid user status","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"warning","filePath":"apps/meteor/server/meteor-methods/users/deleteCustomUserStatus.ts","lineNumber":23,"sourceCode":"\nimport { hasPermissionAsync } from '../../lib/authorization/hasPermission';\nimport { methodDeprecationLogger } from '../../lib/deprecationWarningLogger';\n\ndeclare module '@rocket.chat/ddp-client' {\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tinterface ServerMethods {\n\t\tdeleteCustomUserStatus(userStatusID: string): Promise<boolean>;\n\t}\n}\n\nexport const deleteCustomUserStatus = async (userId: string, userStatusID: string): Promise<boolean> => {\n\tif (!(await hasPermissionAsync(userId, 'manage-user-status'))) {\n\t\tthrow new Meteor.Error('not_authorized');\n\t}\n\n\tconst userStatus = await CustomUserStatus.findOneAndDeleteById(userStatusID);\n\tif (userStatus == null) {\n\t\tthrow new Meteor.Error('Custom_User_Status_Error_Invalid_User_Status', 'Invalid user status', { method: 'deleteCustomUserStatus' });\n\t}\n\n\tvoid api.broadcast('user.deleteCustomStatus', userStatus);\n\n\treturn true;\n};\n\nMeteor.methods<ServerMethods>({\n\tasync deleteCustomUserStatus(userStatusID) {\n\t\tmethodDeprecationLogger.method('deleteCustomUserStatus', '9.0.0', '/v1/custom-user-status.delete');\n\t\tif (!this.userId) {\n\t\t\tthrow new Meteor.Error('not_authorized');\n\t\t}\n\n\t\treturn deleteCustomUserStatus(this.userId, userStatusID);\n\t},\n});\n","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/users/deleteCustomUserStatus.ts#L5-L41","documentation":"`deleteCustomUserStatus` (exported helper used by the Meteor method and its REST counterpart) performs `CustomUserStatus.findOneAndDeleteById(userStatusID)` and throws `Custom_User_Status_Error_Invalid_User_Status` when the lookup-and-delete returns null — i.e. no custom user status exists with that id. Permission is checked first (`manage-user-status` → `not_authorized`), so reaching this error means you were authorized but the record was not found.","triggerScenarios":"Calling `deleteCustomUserStatus(userStatusID)` with an id that does not exist or was already deleted: double-submit of a delete button, stale list of statuses in the admin UI, or an id typo/wrong environment (e.g. dev id used against production).","commonSituations":"Race between two admins deleting the same status; front-end list not refreshed after a delete; sync scripts replaying deletions; ids copied between workspaces where the status was never created.","solutions":["Fetch the current list first (`GET /api/v1/custom-user-status.list`) and use ids from that response.","Treat this error as idempotent success when the goal is 'make sure it is gone'.","Refresh the admin UI list after every delete so stale ids are never reused.","Confirm you are targeting the intended workspace/environment for the given id."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// only delete ids that currently exist\nconst statuses = await (await fetch('/api/v1/custom-user-status.list', { headers: authHeaders })).json();\nconst exists = statuses.customUserStatuses.some(({ _id }) => _id === statusId);\nif (exists) {\n  await Meteor.callAsync('deleteCustomUserStatus', statusId);\n}","typeGuard":"const isKnownStatusId = (id: string, known: string[]): boolean => known.includes(id);","tryCatchPattern":"try {\n  await Meteor.callAsync('deleteCustomUserStatus', statusId);\n} catch (e: any) {\n  if (e?.error === 'Custom_User_Status_Error_Invalid_User_Status') {\n    return; // already deleted - treat as success (idempotent)\n  }\n  throw e;\n}","preventionTips":["Always pick ids from a freshly fetched custom-user-status list.","Refresh the list after every create/delete to avoid stale ids.","Make deletion flows idempotent so replays do not surface errors."],"tags":["meteor","custom-user-status","delete","idempotency"],"backgroundTag":"record-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}