{"record":{"id":"e1a00d7928270ac5","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-user-e1a00d","errorCode":"error-invalid-user","errorMessage":"Invalid user","messagePattern":"Invalid user","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/users/getUserStatusText.ts","lineNumber":20,"sourceCode":"import { Meteor } from 'meteor/meteor';\n\nimport { methodDeprecationLogger } from '../../lib/deprecationWarningLogger';\nimport { getUsersHiddenFrom } from '../../lib/statusVisibility/hiddenUsers';\nimport { getStatusText } from '../../lib/users/getStatusText';\n\ndeclare module '@rocket.chat/ddp-client' {\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tinterface ServerMethods {\n\t\tgetUserStatusText(userId: string): Promise<string | undefined>;\n\t}\n}\n\nMeteor.methods<ServerMethods>({\n\tasync getUserStatusText(userId) {\n\t\tmethodDeprecationLogger.method('getUserStatusText', '9.0.0', '/v1/users.presence');\n\t\tconst currentUserId = Meteor.userId();\n\t\tif (!currentUserId) {\n\t\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'getUserStatusText' });\n\t\t}\n\n\t\tconst hidden = await getUsersHiddenFrom(currentUserId);\n\n\t\treturn hidden?.has(userId) ? undefined : getStatusText(userId);\n\t},\n});\n","sourceCodeStart":2,"sourceCodeEnd":28,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/2a7de457074cbb4d4373fbd9a4e5bea292c9c764/apps/meteor/server/meteor-methods/users/getUserStatusText.ts#L2-L28","documentation":"The getUserStatusText DDP method refuses to run because Meteor.userId() is null — the connection has no authenticated user. It only checks that some user is logged in; the target userId is passed through to getStatusText unchecked here. The method is deprecated since 9.0.0 in favor of REST /v1/users.presence.","triggerScenarios":"Meteor.callAsync('getUserStatusText', userId) from an anonymous or logged-out DDP connection, or after the resume token expired mid-session.","commonSituations":"Status components rendered on guest/preview pages; long-open tabs with expired tokens; calls fired during a logout race.","solutions":["Guard the call with Meteor.userId() and only fetch status for authenticated sessions","Re-login on this error and retry once","Migrate to the REST presence endpoint /v1/users.presence with an authenticated token"],"exampleFix":"// before\nMeteor.callAsync('getUserStatusText', targetUserId);\n\n// after\nif (Meteor.userId()) {\n\tawait Meteor.callAsync('getUserStatusText', targetUserId);\n}","handlingStrategy":"validation","validationCode":"if (!Meteor.userId()) {\n\treturn undefined; // anonymous views get no status text\n}\nreturn Meteor.callAsync('getUserStatusText', userId);","typeGuard":null,"tryCatchPattern":"try {\n\tawait Meteor.callAsync('getUserStatusText', userId);\n} catch (err) {\n\tif ((err as { error?: string }).error === 'error-invalid-user') {\n\t\t// session dropped — re-authenticate and retry once\n\t}\n}","preventionTips":["Gate presence lookups on an authenticated session","Do not call user-scoped methods from guest/preview render paths","Migrate to REST /v1/users.presence (deprecation target)"],"tags":["meteor","ddp","authentication","presence","deprecation"],"backgroundTag":"user-not-authenticated","analyzedSha":"2a7de457074cbb4d4373fbd9a4e5bea292c9c764","analyzedAt":"2026-08-21T15:01:34.830Z","contentChangedAt":"2026-08-21T15:01:34.830Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}