RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-user
error-invalid-user
Error message
Invalid user
What it means
Authentication gate of the cleanRoomHistory Meteor method wrapper: after the check() validations of latest/oldest/inclusive/limit/excludePinned/filesOnly/ignoreThreads/fromUsers, Meteor.userId() returned null. The method requires an authenticated DDP connection because history cleaning is a permissioned, destructive action.
Source
Thrown at apps/meteor/server/meteor-methods/rooms/cleanRoomHistory.ts:94
ignoreDiscussion = true,
filesOnly = false,
fromUsers = [],
ignoreThreads,
}) {
check(roomId, String);
check(latest, Date);
check(oldest, Date);
check(inclusive, Boolean);
check(limit, Match.Maybe(Number));
check(excludePinned, Match.Maybe(Boolean));
check(filesOnly, Match.Maybe(Boolean));
check(ignoreThreads, Match.Maybe(Boolean));
check(fromUsers, Match.Maybe([String]));
const userId = Meteor.userId();
if (!userId) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'cleanRoomHistory' });
}
return cleanRoomHistoryMethod(userId, {
roomId,
latest,
oldest,
inclusive,
limit,
excludePinned,
ignoreDiscussion,
filesOnly,
fromUsers,
ignoreThreads,
});
},
});
View on GitHub (pinned to b2c16d5842)
Solutions
- Ensure Meteor.userId() is set before calling; await login on the client.
- Re-authenticate when the session has expired.
- Use the REST cleaning endpoint (POST /api/v1/rooms.cleanHistory) with token auth for scheduled jobs.
Example fix
// before
Meteor.call('cleanRoomHistory', roomId, latest, oldest);
// after
if (!Meteor.userId()) {
await relogin();
}
Meteor.call('cleanRoomHistory', roomId, latest, oldest); Defensive patterns
Strategy: validation
Validate before calling
if (!Meteor.userId()) {
// cleanRoomHistory needs an authenticated connection - log in first
} Try / catch
try {
await Meteor.callAsync('cleanRoomHistory', roomId, latest, oldest);
} catch (e) {
if (e instanceof Meteor.Error && e.error === 'error-invalid-user') {
await relogin(); // then let the user retry once
return;
}
throw e;
} Prevention
- Gate destructive admin tooling behind a logged-in, permissioned session.
- Use REST rooms.cleanHistory with token auth for scheduled pruning jobs.
- Send Date objects (not strings) for latest/oldest so the check() validations pass first.
When it happens
Trigger: Calling Meteor.call('cleanRoomHistory', ...) on a connection without login or with an expired token; server-side invocation outside a user context.
Common situations: Prune tooling loaded before login completes; sessions invalidated by restarts or password changes; scripts skipping the DDP login step.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/cef8eb6b31c3cbc4.
Report an issue: GitHub.