{"record":{"id":"07a72f9a25c484b2","repo":"RocketChat/Rocket.Chat","slug":"a-new-user-type-has-been-added-that-the-apps-don-t","errorCode":null,"errorMessage":"A new user type has been added that the Apps don't know about? \"${type}\"","messagePattern":"A new user type has been added that the Apps don't know about\\? \"(.+?)\"","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"apps/meteor/app/apps/server/converters/codecs/enums.ts","lineNumber":39,"sourceCode":"\n/**\n * Rocket.Chat `IUser['type']` <-> Apps-Engine `UserType`.\n * Mirrors `AppUsersConverter._convertUserTypeToEnum`.\n */\nexport const UserTypeCodec = z.codec(z.any(), z.any(), {\n\tdecode: (type): string => {\n\t\tswitch (type) {\n\t\t\tcase 'user':\n\t\t\t\treturn UserType.USER;\n\t\t\tcase 'bot':\n\t\t\t\treturn UserType.BOT;\n\t\t\tcase 'app':\n\t\t\t\treturn UserType.APP;\n\t\t\tcase '':\n\t\t\tcase undefined:\n\t\t\t\treturn UserType.UNKNOWN;\n\t\t\tdefault:\n\t\t\t\tconsole.warn(`A new user type has been added that the Apps don't know about? \"${type}\"`);\n\t\t\t\treturn type.toUpperCase();\n\t\t}\n\t},\n\t// The reverse converter assigns `user.type` straight back onto the document.\n\tencode: (type): string => type,\n});\n\n/**\n * Rocket.Chat `IUser['statusConnection']` <-> Apps-Engine `UserStatusConnection`.\n * Mirrors the value mapping of `AppUsersConverter._convertStatusConnectionToEnum`. The legacy\n * `console.warn` (which includes the affected user's id/username) stays in the converter, since\n * that context is not available to a standalone codec.\n */\nexport const UserStatusConnectionCodec = z.codec(z.any(), z.any(), {\n\tdecode: (status): string => {\n\t\tswitch (status) {\n\t\t\tcase 'offline':\n\t\t\t\treturn UserStatusConnection.OFFLINE;","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/app/apps/server/converters/codecs/enums.ts#L21-L57","documentation":"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.","triggerScenarios":"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).","commonSituations":"Version skew between core and apps-engine during upgrades; forks or plugins adding their own user types; legacy/imported users with unexpected type strings.","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"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"const KNOWN_USER_TYPES = new Set(['user', 'bot', 'app', '']);\n\nfunction isKnownUserType(type: string | undefined): type is 'user' | 'bot' | 'app' | '' | undefined {\n\treturn type === undefined || KNOWN_USER_TYPES.has(type);\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["apps-engine","users","enums","codecs","data-quality"],"backgroundTag":"unknown-enum-value","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}