RocketChat/Rocket.Chat · error · Meteor.Error
invalid-channel
invalid-channel
Error message
invalid-channel
What it means
While resolving an incoming-webhook channel target (processWebhookMessage.ts:53-94), channel strings not prefixed with '#' or '@' fall into the default branch: the room is looked up by name/id (with auto-join), then as a direct room containing the webhook user and the value treated as a user id; if neither matches, the server throws Meteor.Error 'invalid-channel'. The same code also surfaces from getRoomByNameOrIdWithOptionToJoin when '#name'/'@user' targets do not exist or have the wrong type.
Source
Thrown at apps/meteor/server/lib/messages/processWebhookMessage.ts:93
errorOnEmpty: false,
});
if (room) {
return room;
}
// We didn't get a room, let's try finding direct messages
room = await getRoomByNameOrIdWithOptionToJoin({
user,
nameOrId: _channelValue,
tryDirectByUserIdOnly: true,
type: 'd',
});
if (room) {
return room;
}
// No room, so throw an error
throw new Meteor.Error('invalid-channel');
}
};
const buildMessage = (messageObj: Payload, defaultValues: DefaultValues) => {
const message: Partial<IMessage> & { parseUrls?: boolean } = {
alias: messageObj.username || messageObj.alias || defaultValues.alias,
msg: trim(messageObj.text || messageObj.msg || ''),
attachments: messageObj.attachments || [],
parseUrls: messageObj.parseUrls !== undefined ? messageObj.parseUrls : !messageObj.attachments,
bot: messageObj.bot,
groupable: messageObj.groupable !== undefined ? messageObj.groupable : false,
tmid: messageObj.tmid,
customFields: messageObj.customFields,
};
if (!_.isEmpty(messageObj.icon_url) || !_.isEmpty(messageObj.avatar)) {
message.avatar = messageObj.icon_url || messageObj.avatar;
} else if (!_.isEmpty(messageObj.icon_emoji) || !_.isEmpty(messageObj.emoji)) {View on GitHub (pinned to b2c16d5842)
Solutions
- Verify the target exists and spell it exactly: '#channelName' for channels/groups, '@username' for direct messages
- Re-create the channel or update the webhook's channel field after renames/deletions
- For DMs, prefer the target's username over raw user id - DM rooms are found (or created) via the user record
- Set separateResponse: true in the payload so one bad channel returns a per-channel error instead of failing the entire delivery
Example fix
// before: { "channel": "#general-typo", ... } -> invalid-channel
// after: { "channel": "#general", "separateResponse": true, ... } Defensive patterns
Strategy: validation
Validate before calling
// before sending, verify the target resolves for the integration user
const room = await getRoomByNameOrIdWithOptionToJoin({
user: botUser,
nameOrId: channel.replace(/^[#@]/, ''),
type: channel.startsWith('@') ? 'd' : undefined,
});
if (!room) throw new Error(`Unknown channel ${channel} - fix the webhook config`); Try / catch
try {
await processWebhookMessage(msg, user, { ... });
} catch (error: any) {
if (error instanceof Meteor.Error && error.error === 'invalid-channel') {
// bad/deleted/renamed channel in payload; fix config, do not blind-retry
alertChannelConfigError(payload.channel);
return;
}
throw error;
} Prevention
- Use '#name' for channels and '@username' for DMs exactly
- Re-check webhook channel config after every channel rename/delete
- Set separateResponse:true for multi-channel deliveries
When it happens
Trigger: An incoming webhook payload with channel '#typo-general', '@deleted-user', a raw room id that no longer exists, or an unknown prefix like '!chan'; '@' targets whose DM room doesn't exist yet and whose id doesn't match a user; channel renamed or deleted after the integration was configured.
Common situations: Webhook integrations (CI, alerting, Zapier-style) configured with a channel that was later renamed/deleted; DM targets whose username changed; sending to private rooms by name from a bot that cannot resolve them; separateResponse=false so the whole request aborts on one bad channel.
Related errors
- error-invalid-room
- Invalid status code
- error-invalid-webhook-response
- Integration payload must be a JSON object, not an array or p
- Attachments should be Array, ignoring value
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/4418fd2d6f03700f.
Report an issue: GitHub.