{"record":{"id":"a533971b42483ecb","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-room-a53397","errorCode":"error-invalid-room","errorMessage":"Invalid room","messagePattern":"Invalid room","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/integrations/incoming/addIncomingIntegration.ts","lineNumber":155,"sourceCode":"\t\tlet record;\n\t\tconst channelType = channel[0];\n\t\tchannel = channel.substr(1);\n\n\t\tswitch (channelType) {\n\t\t\tcase '#':\n\t\t\t\trecord = await Rooms.findOne({\n\t\t\t\t\t$or: [{ _id: channel }, { name: channel }],\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase '@':\n\t\t\t\trecord = await Users.findOne({\n\t\t\t\t\t$or: [{ _id: channel }, { username: channel }],\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (!record) {\n\t\t\tthrow new Meteor.Error('error-invalid-room', 'Invalid room', {\n\t\t\t\tmethod: 'addIncomingIntegration',\n\t\t\t});\n\t\t}\n\n\t\tif (\n\t\t\t!(await hasAllPermissionAsync(userId, ['manage-incoming-integrations', 'manage-own-incoming-integrations'])) &&\n\t\t\t!(await Subscriptions.findOneByRoomIdAndUserId(record._id, userId, { projection: { _id: 1 } }))\n\t\t) {\n\t\t\tthrow new Meteor.Error('error-invalid-channel', 'Invalid Channel', {\n\t\t\t\tmethod: 'addIncomingIntegration',\n\t\t\t});\n\t\t}\n\t}\n\n\tconst strippedIntegrationData = removeEmpty(integrationData);\n\n\tconst { insertedId } = await Integrations.insertOne(strippedIntegrationData);\n","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/integrations/incoming/addIncomingIntegration.ts#L137-L173","documentation":"Thrown by addIncomingIntegration while resolving each channel target. The leading '#' or '@' is stripped (channel.substr(1)), then '#x' is looked up in Rooms by _id or name and '@x' in Users by _id or username. If no document matches, the target does not exist and 'error-invalid-room' is thrown. This is a data lookup failure, not a permission failure.","triggerScenarios":"'#genral' (typo); room renamed or deleted between selection and submit; '#General' where the room name is 'general' (names are lowercase, case-sensitive here); '@former.employee' whose account was deleted.","commonSituations":"Integration forms storing stale room lists; provisioning scripts that create integrations before creating the channels; users typing display names like 'General Chat' instead of the slug 'general-chat'.","solutions":["Use the exact room name (lowercase slug from the room's URL, without the #) for room targets","Create the room or user first, then create the integration","Verify targets ahead of time from server code with Rooms.findOne({ name }) / Users.findOneByUsername or via GET /api/v1/channels.info"],"exampleFix":"// before\nMeteor.callAsync('addIncomingIntegration', { ...integration, channel: '#General Chat' }); // no room named 'General Chat'\n// after\nawait Meteor.callAsync('createChannel', 'general-chat', ['rocket.cat']); // ensure the room exists\nMeteor.callAsync('addIncomingIntegration', { ...integration, channel: '#general-chat' });","handlingStrategy":"validation","validationCode":"// server-side caller: resolve every target before creating the integration\nimport { Rooms, Users } from '@rocket.chat/models';\nfor (const entry of integration.channel.split(',')) {\n  const type = entry.trim()[0]; const name = entry.trim().slice(1);\n  const record = type === '#' ? await Rooms.findOne({ $or: [{ _id: name }, { name }] }) : await Users.findOne({ $or: [{ _id: name }, { username: name }] });\n  if (!record) throw new Error(`target does not exist: ${entry.trim()}`);\n}\nawait Meteor.callAsync('addIncomingIntegration', integration);","typeGuard":null,"tryCatchPattern":"try {\n  await Meteor.callAsync('addIncomingIntegration', integration);\n} catch (err) {\n  if (err instanceof Meteor.Error && err.error === 'error-invalid-room') { /* re-validate room list, offer room picker */ }\n}","preventionTips":["Select channels from the room directory, never free-typed names","Create rooms before integrations in provisioning order","Re-check targets when re-deploying to another environment"],"tags":["rocket-chat","incoming-integration","room-not-found","channel-validation","meteor-method"],"backgroundTag":"room-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}