RocketChat/Rocket.Chat · warning

The user ${user.username} (${user._id}) does not have a vali

Error message

The user ${user.username} (${user._id}) does not have a valid status (offline, online, away, or busy). It is currently: "${statusConnection}"

What it means

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.

Source

Thrown at apps/meteor/app/apps/server/converters/codecs/users.ts:23

import { UserStatusConnectionCodec, UserTypeCodec } from './enums';

const VALID_STATUS_CONNECTIONS = new Set(['offline', 'online', 'away', 'busy']);

/**
 * Rocket.Chat `IUser` <-> Apps-Engine `IAppsUser`.
 *
 * Both directions are bespoke (no `_unmappedProperties_` bucket): `decode` mirrors `convertToApp`
 * and `encode` mirrors `convertToRocketChat`. Enum fields go through the shared enum codecs. The
 * contextual "invalid status" warning stays here (rather than in `UserStatusConnectionCodec`)
 * because it needs the user's id/username. On the `encode` side `utcOffset` falls back to the legacy
 * misspelled `utfOffset` property, so app users that only carry the historical typo still convert.
 */
export const UserCodec = z.codec(z.custom<IUser>(), z.custom<IAppsUser>(), {
	decode: (user): IAppsUser => {
		const { statusConnection } = user;
		if (typeof statusConnection !== 'undefined' && !VALID_STATUS_CONNECTIONS.has(statusConnection)) {
			console.warn(
				`The user ${user.username} (${user._id}) does not have a valid status (offline, online, away, or busy). It is currently: "${statusConnection}"`,
			);
		}

		return {
			id: user._id,
			username: user.username,
			emails: user.emails,
			type: z.decode(UserTypeCodec, user.type),
			isEnabled: user.active,
			name: user.name,
			roles: user.roles,
			bio: user.bio,
			status: user.status,
			statusText: user.statusText,
			statusConnection: z.decode(UserStatusConnectionCodec, statusConnection),
			utcOffset: user.utcOffset,
			createdAt: user.createdAt,

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Find offending documents: db.users.find({ statusConnection: { $nin: ['offline', 'online', 'away', 'busy', null] } }) and fix or unset the field
  2. If the value is mis-cased or misspelled, update it to the closest valid value ('Offline' -> 'offline')
  3. If you write users programmatically, restrict statusConnection to the four constants (reuse UserStatusConnection from @rocket.chat/core-typings)
  4. Re-run the app action afterwards to confirm the warn disappears

Example fix

// before: user document carries an invalid status
// db.users.findOne({ username: 'john' }).statusConnection === 'Invisible'

db.users.find({ statusConnection: { $nin: ['offline', 'online', 'away', 'busy', null] } })

// after: unset the invalid field so the codec treats it as not-set
db.users.updateMany(
  { statusConnection: { $nin: ['offline', 'online', 'away', 'busy', null] } },
  { $unset: { statusConnection: 1 } }
)
Defensive patterns

Strategy: type-guard

Validate before calling

const VALID_STATUS_CONNECTIONS = new Set(['offline', 'online', 'away', 'busy']);

const normalizeUserStatus = (user: IUser): IUser =>
  user.statusConnection && !VALID_STATUS_CONNECTIONS.has(user.statusConnection)
    ? { ...user, statusConnection: undefined }
    : user;
// apply before handing users to any Apps-Engine conversion

Type guard

type StatusConnection = 'offline' | 'online' | 'away' | 'busy';

const isValidStatusConnection = (value: unknown): value is StatusConnection =>
  typeof value === 'string' && VALID_STATUS_CONNECTIONS.has(value as StatusConnection);

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/2efa6fe05dc9b070. Report an issue: GitHub.