RocketChat/Rocket.Chat · warning
A new user type has been added that the Apps don't know abou
Error message
A new user type has been added that the Apps don't know about? "${type}" What it means
This codec converts a Rocket.Chat user document's type field into the Apps-Engine UserType enum. The switch covers 'user', 'bot', 'app' and empty/undefined; anything else hits the default branch, warns, and passes the raw value uppercased to the engine — which may not be a valid UserType member, so apps receiving such a user can misbehave or mislabel it.
Source
Thrown at apps/meteor/app/apps/server/converters/codecs/enums.ts:39
/**
* Rocket.Chat `IUser['type']` <-> Apps-Engine `UserType`.
* Mirrors `AppUsersConverter._convertUserTypeToEnum`.
*/
export const UserTypeCodec = z.codec(z.any(), z.any(), {
decode: (type): string => {
switch (type) {
case 'user':
return UserType.USER;
case 'bot':
return UserType.BOT;
case 'app':
return UserType.APP;
case '':
case undefined:
return UserType.UNKNOWN;
default:
console.warn(`A new user type has been added that the Apps don't know about? "${type}"`);
return type.toUpperCase();
}
},
// The reverse converter assigns `user.type` straight back onto the document.
encode: (type): string => type,
});
/**
* Rocket.Chat `IUser['statusConnection']` <-> Apps-Engine `UserStatusConnection`.
* Mirrors the value mapping of `AppUsersConverter._convertStatusConnectionToEnum`. The legacy
* `console.warn` (which includes the affected user's id/username) stays in the converter, since
* that context is not available to a standalone codec.
*/
export const UserStatusConnectionCodec = z.codec(z.any(), z.any(), {
decode: (status): string => {
switch (status) {
case 'offline':
return UserStatusConnection.OFFLINE;View on GitHub (pinned to b2c16d5842)
Solutions
- Upgrade the Rocket.Chat server so the bundled apps-engine codec knows the new user type
- Audit the users collection for unexpected type values and normalize them to 'user', 'bot' or 'app'
- If you own the custom type, add an explicit case mapping in the codec instead of relying on the uppercased default
Defensive patterns
Strategy: type-guard
Type guard
const KNOWN_USER_TYPES = new Set(['user', 'bot', 'app', '']);
function isKnownUserType(type: string | undefined): type is 'user' | 'bot' | 'app' | '' | undefined {
return type === undefined || KNOWN_USER_TYPES.has(type);
} Prevention
- Keep core and the bundled apps-engine versions in sync so codecs know every user type the server writes
- Never write custom type strings to the users collection; extend the codec mapping instead
- Normalize legacy/imported users to 'user', 'bot' or 'app' before they reach app bridges
When it happens
Trigger: A user document whose type is a newer or custom value (added by a newer core version than the apps-engine codec bundled with the server, or written by third-party code) reaching an app via a bridge conversion (e.g. user payload to an app).
Common situations: Version skew between core and apps-engine during upgrades; forks or plugins adding their own user types; legacy/imported users with unexpected type strings.
Related errors
- The user ${user.username} (${user._id}) does not have a vali
- Creating normal users is currently not supported
- User not provided
- Invalid user id
- error-cannot-delete-app-user
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/07a72f9a25c484b2.
Report an issue: GitHub.