RocketChat/Rocket.Chat · error · Error
Invalid username
Error message
Invalid username
What it means
Thrown by AppMessageBridge.typing when scope is 'room' but username is falsy. Room-scoped typing notifications are broadcast under a username, so the bridge cannot emit the user-activity event without one and rejects the call. It is a precondition on the typing descriptor for room scope.
Source
Thrown at apps/meteor/app/apps/server/bridges/messages.ts:110
// #TODO: #AppsEngineTypes - Remove explicit types and typecasts once the apps-engine definition/implementation mismatch is fixed.
const msg: IMessage | undefined = await this.orch.getConverters()?.get('messages').convertAppMessage(message);
const convertedMessage = msg as IMessage;
const users = (await Subscriptions.findByRoomIdWhenUserIdExists(room.id, { projection: { 'u._id': 1 } }).toArray()).map((s) => s.u._id);
await Users.findByIds(users, { projection: { _id: 1 } }).forEach(
({ _id }: { _id: string }) =>
void api.broadcast('notify.ephemeralMessage', _id, room.id, {
...convertedMessage,
}),
);
}
protected async typing({ scope, id, username, isTyping }: ITypingDescriptor): Promise<void> {
switch (scope) {
case 'room':
if (!username) {
throw new Error('Invalid username');
}
notifications.notifyRoom(id, 'user-activity', username, isTyping ? ['user-typing'] : []);
return;
default:
throw new Error('Unrecognized typing scope provided');
}
}
private isValidReaction(reaction: Reaction): boolean {
return reaction.startsWith(':') && reaction.endsWith(':');
}
protected async addReaction(messageId: string, userId: string, reaction: Reaction): Promise<void> {
if (!this.isValidReaction(reaction)) {
throw new Error('Invalid reaction');
}
View on GitHub (pinned to f9d3ec372b)
Solutions
- Set username to the typing user's username whenever scope is 'room'.
- Resolve the user via the read accessor and use its username field.
- Add a guard: if (scope === 'room' && !username) fail fast with a clear message.
- Validate the ITypingDescriptor shape before calling the notifier.
Example fix
// before
await app.getModify().typing({ scope: 'room', id: room.id, username: undefined, isTyping: true });
// after
if (!user.username) {
throw new Error('Cannot send typing indicator without a username');
}
await app.getModify().typing({ scope: 'room', id: room.id, username: user.username, isTyping: true }); Defensive patterns
Strategy: validation
Validate before calling
function assertRoomTypingDescriptor(descriptor: ITypingDescriptor): asserts descriptor is ITypingDescriptor & { username: string } {
if (descriptor.scope === 'room' && !descriptor.username) {
throw new Error('Room-scoped typing requires a username');
}
}
assertRoomTypingDescriptor(descriptor);
await app.getModify().typing(descriptor); Type guard
const isRoomTypingWithUsername = (d: ITypingDescriptor): d is ITypingDescriptor & { scope: 'room'; username: string } =>
d.scope === 'room' && typeof d.username === 'string' && d.username.length > 0; Try / catch
try {
await app.getModify().typing(descriptor);
} catch (e) {
if ((e as Error).message === 'Invalid username') {
// resolve the user's username and retry
}
throw e;
} Prevention
- Always set username for room-scoped typing descriptors.
- Resolve the user via the read accessor and use its username field.
- Validate the ITypingDescriptor shape before calling the notifier.
When it happens
Trigger: An App calls the typing notifier (e.g. app.getModify().typing(...)) with scope 'room' and username undefined/null/empty, e.g. the App did not set the typing user's username.
Common situations: App constructs an ITypingDescriptor without username; App reads the user from context where username is absent; App confuses userId with username; refactoring dropped the username field.
Related errors
- Unrecognized typing scope provided
- Invalid token for livechat message
- Invalid editor assigned to the message for the update.
- Invalid message id
- Invalid Api parameter provided, it must be a valid IApi obje
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/80dbc630943c2ee9.
Report an issue: GitHub.