RocketChat/Rocket.Chat · error · Error
Room with id not found
Error message
Room with id ${transferData.room} not found What it means
UserDataFiles (GDPR export downloads) resolves the requester via FileUpload.getRequestUserId — rc_uid/rc_token from the query or cookies, or x-user-id/x-auth-token headers — and only permits the export's owner (uid === file.userId). Missing credentials, an invalid/expired token, or any other user yields a bodyless 403. This is stricter than room-based upload protection: exports are owner-only, always.
Solutions
- Download the export while logged in as the user who requested it, using the link from their notification/email
- Pass x-user-id and x-auth-token headers (or rc_uid/rc_token query params) of the owner on programmatic requests
- If the token expired, log in again and reopen the export link
- Do not try to bypass with admin privileges — the check is owner identity, not permission
Example fix
// before
await fetch(`${site}/file-upload/${fileId}/${name}`);
// after: authenticate as the owner
await fetch(`${site}/file-upload/${fileId}/${name}`, { headers: { 'x-user-id': uid, 'x-auth-token': token } }); Defensive patterns
Strategy: validation
Validate before calling
const uid = await FileUpload.getRequestUserId(req);
if (!uid || uid !== file.userId) { /* do not fetch; have the owner's session make the request */ } Type guard
const isOwnerRequest = (requesterId?: string, ownerId: string): boolean => requesterId === ownerId;
Try / catch
On 403 from a user-data export link, redirect to login and retry once as the owner; a second 403 means the authenticated user is not the owner — surface that explicitly.
Prevention
- Send x-user-id/x-auth-token (or rc_uid/rc_token) on every export download
- Never forward export links between users — ownership is enforced strictly
- Expire export links server-side when tokens would outlive sessions
When it happens
Trigger: Downloading another user's export link while authenticated as someone else (including admins); anonymous fetch of an export URL; rc_token expired between the export email and the click; automated fetchers that strip cookies/headers.
Common situations: Forwarded export links; curl/wget downloads without credentials; admins attempting to fetch users' exports directly instead of through the proper flow; sessions expiring before download.
Related errors
- auth option should be of the form "username:password"
- 403
- error-not-authorized
- cannot-access-room
- Command does not exist in the system currently (or it is…
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/1ef9e61fff38e543.
Report an issue: GitHub.
Appendix: source
Thrown at apps/meteor/app/apps/server/bridges/listeners.ts:443
const [agentData] = args.payload;
return this.orch
.getManager()
.getListenerManager()
.executeListener(args.event, {
room: (await this.orch.getConverters().get('rooms').convertRoom(agentData.room)) as IAppsLivechatRoom,
agent: this.orch.getConverters().get('users').convertToApp(agentData.user),
});
case AppInterface.IPostLivechatRoomTransferred: {
const [transferData] = args.payload;
const converter = transferData.type === LivechatTransferEventType.AGENT ? 'users' : 'departments';
const room = await this.orch.getConverters().get('rooms').convertById(transferData.room);
const from = await this.orch.getConverters().get(converter).convertById(transferData.from);
const to = await this.orch.getConverters().get(converter).convertById(transferData.to);
if (!room) {
throw new Error(`Room with id ${transferData.room} not found`);
}
if (!to) {
throw new Error(`Transfer to entity with id ${transferData.to} not found`);
}
return this.orch
.getManager()
.getListenerManager()
.executeListener(args.event, {
room,
from: from as NonNullable<typeof from>, // type definition in the apps-engine seems to be incorrect
to,
type: transferData.type,
});
}
case AppInterface.IPostLivechatGuestSaved: {View on GitHub (pinned to b2c16d5842)