RocketChat/Rocket.Chat · error · Error
invalid-param
invalid-param
Error message
invalid-param
What it means
POST livechat/room.resumeOnHold manually checks that body roomId is present and not only whitespace, throwing invalid-param before the room lookup. This backs up the isLivechatRoomResumeOnHoldProps schema, which permits the field to be missing or blank.
Source
Thrown at apps/meteor/ee/server/api/v1/omnichannel/rooms.ts:61
return API.v1.success();
},
},
);
API.v1.addRoute(
'livechat/room.resumeOnHold',
{
authRequired: true,
permissionsRequired: ['view-l-room'],
validateParams: isLivechatRoomResumeOnHoldProps,
license: ['livechat-enterprise'],
},
{
async post() {
const { roomId } = this.bodyParams;
if (!roomId || roomId.trim() === '') {
throw new Error('invalid-param');
}
type Room = Pick<IOmnichannelRoom, '_id' | 't' | 'open' | 'onHold' | 'servedBy' | 'u' | 'lastMessage'>;
const room = await LivechatRooms.findOneById<Room>(roomId, {
projection: { t: 1, open: 1, onHold: 1, servedBy: 1 },
});
if (!room) {
throw new Error('error-invalid-room');
}
const subscription = await Subscriptions.findOneByRoomIdAndUserId(roomId, this.userId, { projection: { _id: 1 } });
if (!subscription && !(await hasPermissionAsync(this.user, 'on-hold-others-livechat-room'))) {
throw new Error('Not_authorized');
}
const { name, username, _id: userId } = this.user;
const onHoldBy = { _id: userId, username, name };View on GitHub (pinned to b2c16d5842)
Solutions
- Send a non-empty trimmed roomId in the body: {"roomId": "<room _id>"}.
- Check the key name — this route wants roomId in the body, not rid in the URL.
- Assert required fields client-side before posting.
Example fix
// before
await api.post('/v1/livechat/room.resumeOnHold', { rid });
// after
await api.post('/v1/livechat/room.resumeOnHold', { roomId: rid }); Defensive patterns
Strategy: validation
Validate before calling
const isNonEmptyRoomId = (v: unknown): v is string => typeof v === 'string' && v.trim().length > 0;
if (!isNonEmptyRoomId(roomId)) throw new Error('roomId (body) is required and must be non-blank');
await api.post('/v1/livechat/room.resumeOnHold', { roomId }); Type guard
const isNonEmptyRoomId = (v: unknown): v is string => typeof v === 'string' && v.trim().length > 0;
Prevention
- Note the asymmetry: this route takes roomId in the body, not rid in the URL.
- Assert required body fields before posting.
- Trim inputs in form layers so whitespace-only values never reach the API.
When it happens
Trigger: POST /api/v1/livechat/room.resumeOnHold with {}, {"roomId": ""} or {"roomId": " "}.
Common situations: Client sending the value under a different key (rid, room_id) because other routes take rid in the URL; an empty form field submitted; JSON bodies built conditionally where the key is dropped.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- invalid-data
- error-room-does-not-exist
- error-invalid-room
- Not_authorized
- This_conversation_is_already_closed
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/ba6426a9b5ccbd29.
Report an issue: GitHub.