RocketChat/Rocket.Chat · error
error-invalid-agent
error-invalid-agent
Error message
error-invalid-agent
What it means
forwardRoomToAgent requires transferData.userId (the target agent); a falsy value throws error-invalid-agent before any database lookup. This is a required-argument guard, not a lookup failure - an existing-but-offline agent produces error-user-is-offline instead.
Source
Thrown at apps/meteor/server/lib/omnichannel/Helper.ts:497
mentionIds: [],
});
}
};
export const forwardRoomToAgent = async (room: IOmnichannelRoom, transferData: TransferData) => {
if (!room?.open) {
return false;
}
logger.debug({
msg: 'Forwarding room to agent',
roomId: room._id,
userId: transferData.userId,
});
const { userId: agentId, clientAction } = transferData;
if (!agentId) {
throw new Error('error-invalid-agent');
}
const user = await Users.findOneOnlineAgentById(
agentId,
settings.get<boolean>('Livechat_enabled_when_agent_idle'),
settings.get<boolean>('Livechat_accept_chats_with_no_agents'),
{},
);
if (!user) {
logger.debug({
msg: 'Agent is offline. Cannot forward',
agentId,
});
throw new Error('error-user-is-offline');
}
const { _id: rid, servedBy: oldServedBy } = room;
const inquiry = await LivechatInquiry.findOneByRoomId(rid, {});
if (!inquiry) {View on GitHub (pinned to b2c16d5842)
Solutions
- Include a non-empty userId in transferData when forwarding to a specific agent
- If forwarding to a department only, use the department path that does not require userId
- Validate the payload shape at the API boundary before invoking the transfer
Example fix
// before
await forwardRoomToAgent(room, { clientAction: 'forward' }, guest);
// after
const { userId } = transferData;
if (!userId) throw new Error('error-invalid-agent');
await forwardRoomToAgent(room, { ...transferData, userId }, guest); Defensive patterns
Strategy: validation
Validate before calling
const isNonEmptyId = (v: unknown): v is string => typeof v === 'string' && v.trim().length > 0;
if (!isNonEmptyId(transferData.userId)) {
throw new Error('error-invalid-agent');
}
await forwardRoomToAgent(room, transferData, guest); Type guard
const isNonEmptyId = (v: unknown): v is string => typeof v === 'string' && v.trim().length > 0;
Try / catch
try {
await forwardRoomToAgent(room, transferData, guest);
} catch (err) {
if (err instanceof Error && err.message === 'error-invalid-agent') {
// payload lost userId - rebuild transferData and resubmit
} else throw err;
} Prevention
- Validate transfer payload shape (userId/departmentId presence) at the API boundary
- Keep the agent picker required when the forward target is an agent
When it happens
Trigger: Calling the livechat transfer/forward flow (e.g. livechat/room.forward REST endpoint) without userId in the payload; building transferData from a form where the agent select was cleared; field-name mismatch such as user_id vs userId.
Common situations: Frontend sends only { roomId, departmentId } but routes into the agent-forward branch; integrations that assume the agent is optional; agent picker cleared before submit.
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
- error-transferring-inquiry-no-department
- error-user-is-offline
- error-invalid-inquiry
- error-selected-agent-room-agent-are-same
- error-transferring-inquiry
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/0438361059391499.
Report an issue: GitHub.