{"record":{"id":"1a877c0166c8159f","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-room-1a877c","errorCode":"error-invalid-room","errorMessage":"Invalid room","messagePattern":"Invalid room","errorType":"validation","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/integrations/lib/validateOutgoingIntegration.ts","lineNumber":83,"sourceCode":"\t\t\tlet record;\n\t\t\tconst channelType = channel[0];\n\t\t\tchannel = channel.substr(1);\n\n\t\t\tswitch (channelType) {\n\t\t\t\tcase '#':\n\t\t\t\t\trecord = await Rooms.findOne({\n\t\t\t\t\t\t$or: [{ _id: channel }, { name: channel }],\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase '@':\n\t\t\t\t\trecord = await Users.findOne({\n\t\t\t\t\t\t$or: [{ _id: channel }, { username: channel }],\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (!record) {\n\t\t\t\tthrow new Meteor.Error('error-invalid-room', 'Invalid room', {\n\t\t\t\t\tfunction: 'validateOutgoing._verifyUserHasPermissionForChannels',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\t!(await hasAllPermissionAsync(userId, ['manage-outgoing-integrations', 'manage-own-outgoing-integrations'])) &&\n\t\t\t\t!(await Subscriptions.findOneByRoomIdAndUserId(record._id, userId, { projection: { _id: 1 } }))\n\t\t\t) {\n\t\t\t\tthrow new Meteor.Error('error-invalid-channel', 'Invalid Channel', {\n\t\t\t\t\tfunction: 'validateOutgoing._verifyUserHasPermissionForChannels',\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction _verifyRetryInformation(integration: IOutgoingIntegration): void {\n\tif (!integration.retryFailedCalls) {","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/integrations/lib/validateOutgoingIntegration.ts#L65-L101","documentation":"Thrown by _verifyUserHasPermissionForChannels when a channel entry starts with '#' or '@' but no matching record exists: '#' entries are looked up in Rooms by _id or name, '@' entries in Users by _id or username. A miss means the referenced room or user does not exist (or is not visible), and validation stops with Meteor.Error code 'error-invalid-room'.","triggerScenarios":"integrations.create/update with channel '#genral' (typo), '#general ' (trailing space), '@former.employee' (deleted user), or a room name that was renamed after the integration form was loaded; also '#' followed by a room _id that does not exist.","commonSituations":"Channel renamed or archived between loading the form and saving; DM target user deleted; copy-pasting display names that differ from the real username (e.g. 'Jane Doe' vs 'jane.doe'); trailing whitespace from CSV splitting.","solutions":["Correct the channel name/username after the '#'/'@' prefix and re-submit","Trim each CSV entry before submitting to avoid invisible whitespace mismatches","Verify existence first: GET /api/v1/channels.info?roomName=... or users.info?username=... for each target"],"exampleFix":"// before\n{ channel: '#genral' } // typo\n\n// after\n{ channel: '#general' }","handlingStrategy":"validation","validationCode":"const name = channel.slice(1).trim();\nconst record = channel.startsWith('#')\n  ? await Rooms.findOne({ $or: [{ _id: name }, { name }] })\n  : await Users.findOne({ $or: [{ _id: name }, { username: name }] });\nif (!record) {\n  throw new Error(`channel ${channel} does not exist`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Resolve channels through an autocomplete against channels.list / users.list instead of free-text entry","Trim CSV entries and re-validate room names right before saving"],"tags":["integrations","outgoing-webhook","channels","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}