{"record":{"id":"2efa6fe05dc9b070","repo":"RocketChat/Rocket.Chat","slug":"the-user-user-username-user-id-does-not-h","errorCode":null,"errorMessage":"The user ${user.username} (${user._id}) does not have a valid status (offline, online, away, or busy). It is currently: \"${statusConnection}\"","messagePattern":"The user (.+?) \\((.+?)\\) does not have a valid status \\(offline, online, away, or busy\\)\\. It is currently: \"(.+?)\"","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"apps/meteor/app/apps/server/converters/codecs/users.ts","lineNumber":23,"sourceCode":"\nimport { UserStatusConnectionCodec, UserTypeCodec } from './enums';\n\nconst VALID_STATUS_CONNECTIONS = new Set(['offline', 'online', 'away', 'busy']);\n\n/**\n * Rocket.Chat `IUser` <-> Apps-Engine `IAppsUser`.\n *\n * Both directions are bespoke (no `_unmappedProperties_` bucket): `decode` mirrors `convertToApp`\n * and `encode` mirrors `convertToRocketChat`. Enum fields go through the shared enum codecs. The\n * contextual \"invalid status\" warning stays here (rather than in `UserStatusConnectionCodec`)\n * because it needs the user's id/username. On the `encode` side `utcOffset` falls back to the legacy\n * misspelled `utfOffset` property, so app users that only carry the historical typo still convert.\n */\nexport const UserCodec = z.codec(z.custom<IUser>(), z.custom<IAppsUser>(), {\n\tdecode: (user): IAppsUser => {\n\t\tconst { statusConnection } = user;\n\t\tif (typeof statusConnection !== 'undefined' && !VALID_STATUS_CONNECTIONS.has(statusConnection)) {\n\t\t\tconsole.warn(\n\t\t\t\t`The user ${user.username} (${user._id}) does not have a valid status (offline, online, away, or busy). It is currently: \"${statusConnection}\"`,\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tid: user._id,\n\t\t\tusername: user.username,\n\t\t\temails: user.emails,\n\t\t\ttype: z.decode(UserTypeCodec, user.type),\n\t\t\tisEnabled: user.active,\n\t\t\tname: user.name,\n\t\t\troles: user.roles,\n\t\t\tbio: user.bio,\n\t\t\tstatus: user.status,\n\t\t\tstatusText: user.statusText,\n\t\t\tstatusConnection: z.decode(UserStatusConnectionCodec, statusConnection),\n\t\t\tutcOffset: user.utcOffset,\n\t\t\tcreatedAt: user.createdAt,","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/app/apps/server/converters/codecs/users.ts#L5-L41","documentation":"Logged (console.warn) by UserCodec whenever a Rocket.Chat user document is converted to an Apps-Engine IAppsUser (any app SDK surface that hands a user to an app, e.g. user context on listeners or getUser calls). The user's statusConnection is defined but not one of 'offline', 'online', 'away', 'busy' (VALID_STATUS_CONNECTIONS in apps/meteor/app/apps/server/converters/codecs/users.ts:8). The conversion continues and the bad value is still passed through UserStatusConnectionCodec, so this is a data-quality warning, not a hard failure.","triggerScenarios":"Any app/API that decodes an IUser while the Mongo Users document has statusConnection set to an arbitrary string: 'invisible', 'Invisible' (wrong case), 'awayy', or values written by migrations or external provisioning. The check is skipped when statusConnection is undefined, so users who never connected never warn.","commonSituations":"Direct database writes or restore/migration jobs setting statusConnection outside the four values; SSO/bridge tooling creating users with preset statuses; databases carried over from old Rocket.Chat versions with different status vocabulary; manual mongo shell edits.","solutions":["Find offending documents: db.users.find({ statusConnection: { $nin: ['offline', 'online', 'away', 'busy', null] } }) and fix or unset the field","If the value is mis-cased or misspelled, update it to the closest valid value ('Offline' -> 'offline')","If you write users programmatically, restrict statusConnection to the four constants (reuse UserStatusConnection from @rocket.chat/core-typings)","Re-run the app action afterwards to confirm the warn disappears"],"exampleFix":"// before: user document carries an invalid status\n// db.users.findOne({ username: 'john' }).statusConnection === 'Invisible'\n\ndb.users.find({ statusConnection: { $nin: ['offline', 'online', 'away', 'busy', null] } })\n\n// after: unset the invalid field so the codec treats it as not-set\ndb.users.updateMany(\n  { statusConnection: { $nin: ['offline', 'online', 'away', 'busy', null] } },\n  { $unset: { statusConnection: 1 } }\n)","handlingStrategy":"type-guard","validationCode":"const VALID_STATUS_CONNECTIONS = new Set(['offline', 'online', 'away', 'busy']);\n\nconst normalizeUserStatus = (user: IUser): IUser =>\n  user.statusConnection && !VALID_STATUS_CONNECTIONS.has(user.statusConnection)\n    ? { ...user, statusConnection: undefined }\n    : user;\n// apply before handing users to any Apps-Engine conversion","typeGuard":"type StatusConnection = 'offline' | 'online' | 'away' | 'busy';\n\nconst isValidStatusConnection = (value: unknown): value is StatusConnection =>\n  typeof value === 'string' && VALID_STATUS_CONNECTIONS.has(value as StatusConnection);","tryCatchPattern":null,"preventionTips":["Never write statusConnection outside the four enum values; reuse UserStatusConnection from @rocket.chat/core-typings","Add a schema check to migration/restore jobs before they touch the users collection","Treat this warn as an audit signal: collect the reported user ids and fix them at the source"],"tags":["apps-engine","user-status","data-quality","console-warn","codecs"],"backgroundTag":"invalid-enum-value","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}