{"record":{"id":"de5f154347903b65","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-channel-de5f15","errorCode":"error-invalid-channel","errorMessage":"Invalid channel","messagePattern":"Invalid channel","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/integrations/incoming/addIncomingIntegration.ts","lineNumber":54,"sourceCode":"\t\t\tscriptEngine: Match.Maybe(String),\n\t\t\toverrideDestinationChannelEnabled: Match.Maybe(Boolean),\n\t\t\tscript: Match.Maybe(String),\n\t\t\tavatar: Match.Maybe(String),\n\t\t}),\n\t);\n\n\tif (\n\t\t!userId ||\n\t\t(!(await hasPermissionAsync(userId, 'manage-incoming-integrations')) &&\n\t\t\t!(await hasPermissionAsync(userId, 'manage-own-incoming-integrations')))\n\t) {\n\t\tthrow new Meteor.Error('not_authorized', 'Unauthorized', {\n\t\t\tmethod: 'addIncomingIntegration',\n\t\t});\n\t}\n\n\tif (!integration.channel || typeof integration.channel.valueOf() !== 'string') {\n\t\tthrow new Meteor.Error('error-invalid-channel', 'Invalid channel', {\n\t\t\tmethod: 'addIncomingIntegration',\n\t\t});\n\t}\n\n\tif (integration.channel.trim() === '') {\n\t\tthrow new Meteor.Error('error-invalid-channel', 'Invalid channel', {\n\t\t\tmethod: 'addIncomingIntegration',\n\t\t});\n\t}\n\n\tconst channels = integration.channel.split(',').map((channel) => channel.trim());\n\n\tfor (const channel of channels) {\n\t\tif (!validChannelChars.includes(channel[0])) {\n\t\t\tthrow new Meteor.Error('error-invalid-channel-start-with-chars', 'Invalid channel. Start with @ or #', {\n\t\t\t\tmethod: 'updateIncomingIntegration',\n\t\t\t});\n\t\t}","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/integrations/incoming/addIncomingIntegration.ts#L36-L72","documentation":"Thrown by the deprecated addIncomingIntegration Meteor method when integration.channel is falsy or not a string. The channel field is a single comma-separated string listing the rooms ('#name') and users ('@username') the incoming webhook may post to. Note the method first runs Meteor's check() requiring channel: String, so missing or non-string values usually surface earlier as a 'Match failed' Match.Error; this explicit error most commonly fires for channel: '' (empty string is falsy).","triggerScenarios":"Meteor.callAsync('addIncomingIntegration', integration) with channel: '' or channel: null (the latter only when calling the exported helper directly, e.g. in tests, since check() intercepts it on the method path).","commonSituations":"A custom integration form was submitted with the channel field left blank; payload built from array.join() on an empty array; migrating from the REST endpoint /api/v1/integrations.create and forgetting the DDP method wants one comma-separated string; calling this DDP method on a 9.0.0+ server where it has been removed.","solutions":["Set channel to a non-empty comma-separated string where every entry starts with # (room) or @ (user), e.g. '#general,@rocket.cat'","If you instead see 'Match failed', the channel is missing or not a string at all - send it as a primitive string, never an array or object","Prefer the REST endpoint POST /api/v1/integrations.create; these Meteor methods are deprecated and removed in 9.0.0"],"exampleFix":"// before\nMeteor.callAsync('addIncomingIntegration', { ...integration, channel: '' });\n// after\nMeteor.callAsync('addIncomingIntegration', { ...integration, channel: '#general,@rocket.cat' });","handlingStrategy":"validation","validationCode":"const channelOk = (channel) => typeof channel === 'string' && channel.length > 0;\nif (!channelOk(integration.channel)) throw new Error('channel must be a non-empty \"#room,@user\" string');\nawait Meteor.callAsync('addIncomingIntegration', integration);","typeGuard":"const isNonEmptyChannelString = (c: unknown): c is string => typeof c === 'string' && c.length > 0;","tryCatchPattern":"try {\n  await Meteor.callAsync('addIncomingIntegration', integration);\n} catch (err) {\n  if (err instanceof Meteor.Error && err.error === 'error-invalid-channel') { /* prompt user for channel */ return; }\n  throw err;\n}","preventionTips":["Type the form payload as INewIncomingIntegration so channel must be a string","Disable submit until the channel field is non-empty","Prefer the REST /v1/integrations.create endpoint for new code"],"tags":["rocket-chat","incoming-integration","meteor-method","channel-validation"],"backgroundTag":"integration-channel-validation","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}