{"record":{"id":"3d375b74428ded6b","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-channel-start-with-chars","errorCode":"error-invalid-channel-start-with-chars","errorMessage":"Invalid channel. Start with @ or #","messagePattern":"Invalid channel\\. Start with @ or #","errorType":"validation","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/integrations/lib/validateOutgoingIntegration.ts","lineNumber":133,"sourceCode":"\tif (integration.channel && Match.test(integration.channel, String) && integration.channel.trim() === '') {\n\t\tdelete integration.channel;\n\t}\n\n\t// Moved to it's own function to satisfy the complexity rule\n\t_verifyRequiredFields(integration);\n\n\tlet channels: string[] = [];\n\tif (outgoingEvents[integration.event].use.channel) {\n\t\tif (!Match.test(integration.channel, String)) {\n\t\t\tthrow new Meteor.Error('error-invalid-channel', 'Invalid Channel', {\n\t\t\t\tfunction: 'validateOutgoing',\n\t\t\t});\n\t\t} else {\n\t\t\tchannels = parseCSV(integration.channel);\n\n\t\t\tfor (const channel of channels) {\n\t\t\t\tif (!validChannelChars.includes(channel[0]) && !scopedChannels.includes(channel.toLowerCase())) {\n\t\t\t\t\tthrow new Meteor.Error('error-invalid-channel-start-with-chars', 'Invalid channel. Start with @ or #', {\n\t\t\t\t\t\tfunction: 'validateOutgoing',\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if (!(await hasPermissionAsync(userId, 'manage-outgoing-integrations'))) {\n\t\tthrow new Meteor.Error('error-invalid-permissions', 'Invalid permission for required Integration creation.', {\n\t\t\tfunction: 'validateOutgoing',\n\t\t});\n\t}\n\n\tconst user = await Users.findOne({ username: integration.username });\n\n\tif (!user) {\n\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user (did you delete the `rocket.cat` user?)', { function: 'validateOutgoing' });\n\t}\n\n\tconst integrationData: IOutgoingIntegration = {","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/integrations/lib/validateOutgoingIntegration.ts#L115-L151","documentation":"Thrown in validateOutgoing when a parsed CSV channel entry neither starts with '@' or '#' nor is one of the scoped tokens ('all_public_channels', 'all_private_groups', 'all_direct_messages'). The prefix tells the server how to resolve the entry — '#' for rooms, '@' for direct-message users — so a bare name is ambiguous and rejected with Meteor.Error code 'error-invalid-channel-start-with-chars'.","triggerScenarios":"integrations.create with channel 'general, dev-team' (no prefixes), 'all public channels' (spelled out instead of the token), or a CSV entry that is an empty string after splitting a trailing comma (channel[0] is undefined).","commonSituations":"Users typing plain room names because the UI hint is missed; data migrated from other chat tools where channels have no sigil; the scoped-token comparison is lowercased but the prefix check is not, so '#General' is fine but 'General' fails.","solutions":["Prefix every entry: '#room-name' for channels, '@username' for DMs, e.g. channel: '#general, @alice'","Use the exact scoped tokens all_public_channels / all_private_groups / all_direct_messages for workspace-wide scopes","Normalize input before submitting: csv.split(',').map((s) => s.trim()).filter(Boolean)"],"exampleFix":"// before\n{ channel: 'general, dev-team' }\n\n// after\n{ channel: '#general, #dev-team' }","handlingStrategy":"validation","validationCode":"const SCOPED = ['all_public_channels', 'all_private_groups', 'all_direct_messages'];\nfor (const ch of parseCSV(channel)) {\n  if (!['@', '#'].includes(ch[0]) && !SCOPED.includes(ch.toLowerCase())) {\n    throw new RangeError(`channel '${ch}' must start with # or @ (or be a scoped token)`);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Auto-prefix user input: '# ' for names typed without a sigil in the UI","Filter empty CSV entries so a trailing comma cannot produce a bogus entry"],"tags":["integrations","outgoing-webhook","channels","validation"],"backgroundTag":"invalid-channel-name","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}