RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-channel
error-invalid-channel
Error message
Invalid Channel
What it means
Thrown by _verifyUserHasPermissionForChannels when a channel entry is one of the workspace-wide scope tokens 'all_private_groups' or 'all_direct_messages' but the creating user lacks the manage-outgoing-integrations permission. Listening across every private group or DM is privileged, so only users holding that permission may register such an integration; 'all_public_channels' is explicitly exempt and needs no permission.
Source
Thrown at apps/meteor/server/lib/integrations/lib/validateOutgoingIntegration.ts:60
});
}
integration.urls = integration.urls.filter((url) => url && url.trim() !== '');
if (integration.urls.length === 0) {
throw new Meteor.Error('error-invalid-urls', 'Invalid URLs', {
function: 'validateOutgoing._verifyRequiredFields',
});
}
}
async function _verifyUserHasPermissionForChannels(userId: IUser['_id'], channels: string[]): Promise<void> {
for (let channel of channels) {
if (scopedChannels.includes(channel)) {
if (channel === 'all_public_channels') {
// No special permissions needed to add integration to public channels
} else if (!(await hasPermissionAsync(userId, 'manage-outgoing-integrations'))) {
throw new Meteor.Error('error-invalid-channel', 'Invalid Channel', {
function: 'validateOutgoing._verifyUserHasPermissionForChannels',
});
}
} else {
let record;
const channelType = channel[0];
channel = channel.substr(1);
switch (channelType) {
case '#':
record = await Rooms.findOne({
$or: [{ _id: channel }, { name: channel }],
});
break;
case '@':
record = await Users.findOne({
$or: [{ _id: channel }, { username: channel }],
});View on GitHub (pinned to b2c16d5842)
Solutions
- Grant the creator's role manage-outgoing-integrations (Admin -> Permissions), then retry
- Or scope the integration to explicit channels ('#private-room') the user belongs to instead of the all_* token
- Use 'all_public_channels' when public-channel coverage is enough — it requires no permission
Example fix
// before — non-admin, workspace-wide private scope
{ channel: 'all_private_groups' }
// after — grant the permission, or list rooms explicitly
// Admin -> Permissions -> role 'user' -> manage-outgoing-integrations = On
{ channel: '#private-room' } Defensive patterns
Strategy: validation
Validate before calling
const privilegedScopes = ['all_private_groups', 'all_direct_messages'];
if (channels.some((c) => privilegedScopes.includes(c)) && !(await hasPermissionAsync(userId, 'manage-outgoing-integrations'))) {
throw new Error('all_private_groups / all_direct_messages require manage-outgoing-integrations');
} Prevention
- Check the creator's permissions before offering the all_private_groups / all_direct_messages options in the UI
- Prefer explicit channel lists or all_public_channels for non-admin users
When it happens
Trigger: A non-admin calls integrations.create/update with channel containing 'all_private_groups' or 'all_direct_messages' (case-sensitive as written in the channel CSV) while their role lacks manage-outgoing-integrations.
Common situations: Power users trying to mirror all DMs or private channels into an external tool; permission sets cloned from a bot role that never included integration management; forgetting that only the public-channel scope is unprivileged.
Related errors
- error-invalid-room
- error-invalid-channel-start-with-chars
- error-invalid-permissions
- not-authorized
- unauthorized
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/d3d97f7d448f8b12.
Report an issue: GitHub.