{"record":{"id":"e1097647ac7b88b5","repo":"RocketChat/Rocket.Chat","slug":"error-action-not-allowed-e10976","errorCode":"error-action-not-allowed","errorMessage":"Auto-Translate is not allowed","messagePattern":"Auto-Translate is not allowed","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/autotranslate/functions/saveSettings.ts","lineNumber":16,"sourceCode":"import { Subscriptions, Rooms } from '@rocket.chat/models';\nimport { check } from 'meteor/check';\nimport { Meteor } from 'meteor/meteor';\n\nimport { hasPermissionAsync } from '../../authorization/hasPermission';\nimport { notifyOnSubscriptionChangedById } from '../../notifyListener';\n\nexport const saveAutoTranslateSettings = async (\n\tuserId: string,\n\trid: string,\n\tfield: string,\n\tvalue: string,\n\toptions: { defaultLanguage: string },\n) => {\n\tif (!(await hasPermissionAsync(userId, 'auto-translate'))) {\n\t\tthrow new Meteor.Error('error-action-not-allowed', 'Auto-Translate is not allowed', {\n\t\t\tmethod: 'autoTranslate.saveSettings',\n\t\t});\n\t}\n\n\tcheck(rid, String);\n\tcheck(field, String);\n\tcheck(value, String);\n\n\tif (['autoTranslate', 'autoTranslateLanguage'].indexOf(field) === -1) {\n\t\tthrow new Meteor.Error('error-invalid-settings', 'Invalid settings field', {\n\t\t\tmethod: 'saveAutoTranslateSettings',\n\t\t});\n\t}\n\n\tconst subscription = await Subscriptions.findOneByRoomIdAndUserId(rid, userId);\n\tif (!subscription) {\n\t\tthrow new Meteor.Error('error-invalid-subscription', 'Invalid subscription', {\n\t\t\tmethod: 'saveAutoTranslateSettings',","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/autotranslate/functions/saveSettings.ts#L1-L34","documentation":"First check in saveAutoTranslateSettings, which backs DDP 'autoTranslate.saveSettings' and 'POST /api/v1/autotranslate.saveSettings': the acting user must hold the 'auto-translate' permission (global scope). It fires before argument validation, so under-privileged users get this even for malformed input.","triggerScenarios":"Calling autotranslate.saveSettings for a user whose roles lack 'auto-translate'; toggling per-room translation from the room settings UI as such a user; a service account saving settings without the permission.","commonSituations":"Auto-Translate enabled but the permission never granted; recently demoted users with stale clients; REST calls with a token whose user was never added to an auto-translate-enabled role.","solutions":["Grant 'auto-translate' to the acting user's role","Confirm the check has no room scope, so the permission must be global","Cache the permission result client-side to avoid repeated failing calls"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const me = await GET '/api/v1/me';\nif (!me.permissions?.includes('auto-translate')) {\n  // skip autotranslate.saveSettings entirely\n}","typeGuard":null,"tryCatchPattern":"try {\n  await POST '/api/v1/autotranslate.saveSettings' { roomId, field, value };\n} catch (e) {\n  if (e.error === 'error-action-not-allowed') {\n    // acting user needs the global 'auto-translate' permission\n  } else {\n    throw e;\n  }\n}","preventionTips":["Grant 'auto-translate' before exposing per-room translate toggles","Remember the check runs before argument validation - fix permissions first when debugging","Avoid calling saveSettings from service accounts that never received the permission"],"tags":["rocket-chat","autotranslate","authorization","rbac","meteor-methods"],"backgroundTag":"permission-denied","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}