{"record":{"id":"57d3f78d9b092b6a","repo":"RocketChat/Rocket.Chat","slug":"error-status-not-allowed","errorCode":"error-status-not-allowed","errorMessage":"Invisible status is disabled","messagePattern":"Invisible status is disabled","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/api/v1/users.ts","lineNumber":2039,"sourceCode":"\t\t\tconst statusExpiresAt = expiresAt ? new Date(expiresAt) : undefined;\n\t\t\tif (statusExpiresAt && Number.isNaN(statusExpiresAt.getTime())) {\n\t\t\t\tthrow new Meteor.Error('error-invalid-date', 'Invalid expiresAt date string', {\n\t\t\t\t\tmethod: 'users.setStatus',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (statusExpiresAt && statusExpiresAt.getTime() <= Date.now()) {\n\t\t\t\tthrow new Meteor.Error('error-invalid-date', 'expiresAt must be a future date', {\n\t\t\t\t\tmethod: 'users.setStatus',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// If status is missing (message-only update), keep the user's chosen status (statusDefault),\n\t\t\t// not the computed status — otherwise a transient auto-away/offline gets pinned as a manual claim.\n\t\t\tconst effectiveStatus = status || user.statusDefault || ('online' as UserStatus);\n\n\t\t\tif (effectiveStatus === 'offline' && !settings.get('Accounts_AllowInvisibleStatusOption')) {\n\t\t\t\tthrow new Meteor.Error('error-status-not-allowed', 'Invisible status is disabled', {\n\t\t\t\t\tmethod: 'users.setStatus',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tawait Presence.setStatus(user._id, effectiveStatus, message, statusExpiresAt);\n\n\t\t\treturn API.v1.success();\n\t\t},\n\t)\n\t.get(\n\t\t'users.getStatus',\n\t\t{\n\t\t\tauthRequired: true,\n\t\t\tquery: isUsersGetStatusParamsGET,\n\t\t\tresponse: {\n\t\t\t\t200: ajv.compile<{ _id: string; status: string; connectionStatus?: string; statusSource?: string; statusExpiresAt?: string }>({\n\t\t\t\t\ttype: 'object',\n\t\t\t\t\tproperties: {","sourceCodeStart":2021,"sourceCodeEnd":2057,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/users.ts#L2021-L2057","documentation":"Thrown by POST users.setStatus when the effective status resolves to 'offline' but the instance setting Accounts_AllowInvisibleStatusOption is disabled. The effective status is computed as the supplied status, else the user's statusDefault, else 'online' - so a user whose statusDefault is 'offline' can hit this even without explicitly sending status:'offline'.","triggerScenarios":"POST /api/v1/users.setStatus with status:'offline', or with status omitted while the user's statusDefault is 'offline', while Accounts_AllowInvisibleStatusOption is false.","commonSituations":"Admin disabled invisible status but a user previously set their default to offline. A client omits status in a message-only update and the user's pinned default is offline.","solutions":["Enable Accounts_AllowInvisibleStatusOption if invisible/appear-offline is intended to be allowed.","When the setting is off, explicitly send a non-offline status, or reset the user's statusDefault away from 'offline' first.","Client: check the public setting and hide the 'invisible' option when disabled."],"exampleFix":"// before - setting off, statusDefault is offline\nPOST('/api/v1/users.setStatus', { message: 'busy' }) // effectiveStatus -> offline -> error\n\n// after\nPOST('/api/v1/users.setStatus', { status: 'away', message: 'busy' })","handlingStrategy":"validation","validationCode":"const allowInvisible = await getSetting('Accounts_AllowInvisibleStatusOption');\nconst effective = body.status || user.statusDefault || 'online';\nif (effective === 'offline' && !allowInvisible) {\n  body.status = user.statusDefault === 'offline' ? 'away' : (user.statusDefault || 'online');\n}","typeGuard":"function isInvisibleAllowed(settingValue, effectiveStatus) {\n  return effectiveStatus !== 'offline' || settingValue === true;\n}","tryCatchPattern":"try { await POST('/api/v1/users.setStatus', body); }\ncatch (e) {\n  if (e?.error === 'error-status-not-allowed') {\n    body.status = 'away'; await POST('/api/v1/users.setStatus', body); return;\n  }\n  throw e;\n}","preventionTips":["Read Accounts_AllowInvisibleStatusOption and hide 'invisible' when off.","When doing a message-only update, also ensure statusDefault is not 'offline' under that setting.","Send an explicit non-offline status to avoid relying on statusDefault."],"tags":["api","users","presence","status","settings","configuration"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}