Skip to content

fix: prevent duplicate livechat rooms on concurrent requests#39087

Merged
sampaiodiego merged 4 commits intodevelopfrom
fix/room-creation-livechat
Mar 17, 2026
Merged

fix: prevent duplicate livechat rooms on concurrent requests#39087
sampaiodiego merged 4 commits intodevelopfrom
fix/room-creation-livechat

Conversation

@ricardogarim
Copy link
Copy Markdown
Member

@ricardogarim ricardogarim commented Feb 26, 2026

When two concurrent requests hit different server instances for the same visitor token, both can create separate rooms because:

  1. TOCTOU gap - Check for existing room happens at API level, create happens deep in call stack
  2. Random _id - createLivechatRoom() uses findOneAndUpdate with random _id in query, so it never finds existing rooms
  3. No unique constraint - No index on v.token for open rooms to reject duplicates

Proposed changes (including videos or screenshots)

We need to enforce that only one open livechat room exists per v.token. However, simply adding a unique index would fail in environments that already contain duplicate open rooms, since MongoDB validates uniqueness when creating the index.

Because this is not a major version, we cannot run data migrations or modify existing records to remove duplicates. To avoid breaking deployments, we introduced a new marker field, _enforceSingleRoom, which is added only to rooms created by this version onward.

The unique partial index applies only to documents with this marker field, meaning legacy rooms are ignored while all new rooms are protected. This ensures forward enforcement without impacting existing data.

{
  key: { 'v.token': 1 },
  unique: true,
  partialFilterExpression: { 't': 'l', 'open': true, '_enforceSingleRoom': true }
}

Issue(s)

Steps to test or reproduce

Reproduce the race condition (before fix)

  1. Set up RC with 2+ server instances (using NATS transporter)
  2. Send concurrent requests to create a room for the same visitor:
# Run these simultaneously
curl "http://localhost:3000/api/v1/livechat/room?token=TEST_TOKEN" &
curl "http://localhost:3000/api/v1/livechat/room?token=TEST_TOKEN" &
  1. Check MongoDB for duplicate rooms:
    db.rocketchat_room.find({ 'v.token': 'TEST_TOKEN', t: 'l', open: true })

Verify the fix

  1. Apply this PR
  2. Repeat the concurrent requests
  3. Verify only one room exists
  4. Verify the room has _enforceSingleRoom: true

Further comments - other solutions explored

Atomic upsert with deterministic query

We considered modifying createLivechatRoom() to rely on a deterministic query based on v.token instead of generating a random _id, using findOneAndUpdate with upsert: true.

According to MongoDB’s atomicity guarantees, findOneAndUpdate with upsert: true is atomic per operation. However, atomicity does not prevent race conditions between concurrent requests. Two parallel operations can both evaluate the query, both see that no document exists, and both proceed to insert a new document with different _id values.

In this scenario, both inserts succeed because there is no unique constraint preventing duplication. MongoDB only rejects duplicate inserts when a unique index exists. Therefore, atomic upsert alone is insufficient to guarantee a single open room per visitor token.

Distributed lock

We also explored implementing a locking mechanism similar to the existing agent lock, using lock fields on the visitor document to serialize room creation.

The idea was to acquire a lock for the visitor, check for an existing open room, and only create a new one if none existed, releasing the lock afterward.

This approach introduces several issues:

  • First, there is a timeout risk: if room creation takes longer than the lock duration, another request may acquire the lock and recreate the race condition;
  • Second, the lock depends on the visitor document already existing, but visitor creation itself is subject to the same race condition;
  • Finally, it adds operational complexity, requiring lock management, retry logic, and timeout configuration.

Summary by CodeRabbit

  • Bug Fixes
    • Prevents duplicate open live chat conversations for the same visitor, reducing race-condition duplicates and improving session reliability.
    • Applies a patch release across relevant packages to deliver the fix.

@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot bot commented Feb 26, 2026

Looks like this PR is ready to merge! 🎉
If you have any trouble, please check the PR guidelines

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cd2dd279-ed73-431b-8305-2a954ff7cf1d

📥 Commits

Reviewing files that changed from the base of the PR and between ab4fedc and 0eae8dd.

📒 Files selected for processing (1)
  • packages/models/src/models/LivechatRooms.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/models/src/models/LivechatRooms.ts
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: CodeQL-Build

Walkthrough

Adds _enforceSingleRoom: true to newly created livechat room documents and a partial unique index on v.token for open livechat rooms with that marker, enforcing a single open livechat room per visitor token at the database level.

Changes

Cohort / File(s) Summary
Livechat Room Initialization
apps/meteor/app/livechat/server/lib/Helper.ts
Add _enforceSingleRoom: true to the insertion object in prepareLivechatRoom so new rooms are marked for unique-index enforcement.
Livechat Rooms Index
packages/models/src/models/LivechatRooms.ts
Add a partial unique index on { 'v.token': 1 } with partialFilterExpression: { t: 'l', open: true, _enforceSingleRoom: true } (index name v.token_1_unique_open_livechat) to prevent duplicate open livechat rooms per visitor token.
Release Metadata
.changeset/fluffy-turtles-admire.md
Add changeset noting patch releases for @rocket.chat/models and @rocket.chat/meteor with a short description of the fix for duplicate open livechat rooms.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Client
participant LivechatServer as Livechat Server
participant MongoDB
Client->>LivechatServer: GET /livechat/room (concurrent requests)
LivechatServer->>MongoDB: findOne open room by v.token
alt no existing open room (both requests)
LivechatServer->>MongoDB: insert room (includes _enforceSingleRoom: true)
MongoDB-->>LivechatServer: insert OK (first request)
LivechatServer-->>Client: return Room A
LivechatServer->>MongoDB: insert room (second concurrent)
MongoDB-->>LivechatServer: duplicate key error (unique index)
LivechatServer->>MongoDB: findOne open room by v.token
MongoDB-->>LivechatServer: returns Room A
LivechatServer-->>Client: return Room A
end

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'fix: prevent duplicate livechat rooms on concurrent requests' directly describes the main objective—preventing race condition duplicates.
Linked Issues check ✅ Passed The implementation fulfills all linked issue requirements: adds _enforceSingleRoom marker field, creates partial unique index on v.token for open rooms, and prevents duplicates without requiring migration.
Out of Scope Changes check ✅ Passed All changes directly address the linked issue: Helper.ts marker addition, LivechatRooms.ts index creation, and changeset documentation are all in-scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Feb 26, 2026

🦋 Changeset detected

Latest commit: 0eae8dd

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 41 packages
Name Type
@rocket.chat/models Patch
@rocket.chat/meteor Patch
@rocket.chat/core-services Patch
@rocket.chat/cron Patch
@rocket.chat/instance-status Patch
@rocket.chat/omni-core Patch
@rocket.chat/server-fetch Patch
@rocket.chat/ui-client Patch
@rocket.chat/account-service Patch
@rocket.chat/authorization-service Patch
@rocket.chat/ddp-streamer Patch
@rocket.chat/omnichannel-transcript Patch
@rocket.chat/presence-service Patch
@rocket.chat/queue-worker Patch
@rocket.chat/abac Patch
@rocket.chat/federation-matrix Patch
@rocket.chat/media-calls Patch
@rocket.chat/omni-core-ee Patch
@rocket.chat/omnichannel-services Patch
@rocket.chat/presence Patch
rocketchat-services Patch
@rocket.chat/network-broker Patch
@rocket.chat/core-typings Patch
@rocket.chat/rest-typings Patch
@rocket.chat/uikit-playground Patch
@rocket.chat/api-client Patch
@rocket.chat/apps Patch
@rocket.chat/ddp-client Patch
@rocket.chat/fuselage-ui-kit Patch
@rocket.chat/gazzodown Patch
@rocket.chat/http-router Patch
@rocket.chat/livechat Patch
@rocket.chat/model-typings Patch
@rocket.chat/ui-avatar Patch
@rocket.chat/ui-contexts Patch
@rocket.chat/ui-voip Patch
@rocket.chat/web-ui-registration Patch
@rocket.chat/license Patch
@rocket.chat/pdf-worker Patch
@rocket.chat/mock-providers Patch
@rocket.chat/ui-video-conf Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codecov
Copy link
Copy Markdown

codecov bot commented Feb 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.97%. Comparing base (afaabea) to head (0eae8dd).
⚠️ Report is 116 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #39087      +/-   ##
===========================================
+ Coverage    70.66%   70.97%   +0.30%     
===========================================
  Files         3191     3199       +8     
  Lines       112965   113466     +501     
  Branches     20451    20714     +263     
===========================================
+ Hits         79829    80529     +700     
+ Misses       31088    30885     -203     
- Partials      2048     2052       +4     
Flag Coverage Δ
e2e 60.42% <ø> (+0.03%) ⬆️
e2e-api 48.19% <ø> (+0.38%) ⬆️
unit 71.67% <ø> (+0.37%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ricardogarim ricardogarim force-pushed the fix/room-creation-livechat branch from 57b0b05 to 5099d8e Compare February 26, 2026 14:11
@ricardogarim ricardogarim force-pushed the fix/room-creation-livechat branch from 5099d8e to 9b052bd Compare February 26, 2026 14:15
@ricardogarim ricardogarim marked this pull request as ready for review March 2, 2026 12:15
@ricardogarim ricardogarim requested review from a team as code owners March 2, 2026 12:15
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 3 files

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
apps/meteor/app/livechat/server/lib/Helper.ts (1)

147-148: Move rationale comments out of implementation code.

Prefer keeping this explanation in PR/migration docs and leaving implementation comment-free.

As per coding guidelines "Avoid code comments in the implementation".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/livechat/server/lib/Helper.ts` around lines 147 - 148, Remove
the two implementation comments that explain the "marker field for unique index
- only new rooms have this field" and "allows index creation to succeed even if
old duplicates exist" from Helper.ts; instead document this rationale in the PR
description or migration docs and leave the implementation code free of
explanatory comments per the coding guideline "Avoid code comments in the
implementation." Ensure no other inline explanatory comments remain near the
marker field usage so the code contains only necessary code-level comments (if
any).
packages/core-typings/src/IRoom.ts (1)

313-315: Keep the new field, but drop inline implementation comments.

The _enforceSingleRoom typing is good; only the explanatory comments should be moved to docs/PR context.

As per coding guidelines "Avoid code comments in the implementation".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core-typings/src/IRoom.ts` around lines 313 - 315, Keep the
_enforceSingleRoom?: boolean; field but remove the two inline implementation
comment lines above it; retain the property declaration exactly as-is (symbol:
_enforceSingleRoom) and move the explanatory text about the marker field and
index behaviour out of code into PR/docs context instead of leaving it in the
IRoom definition.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/meteor/app/livechat/server/lib/Helper.ts`:
- Around line 149-150: The object currently sets _enforceSingleRoom: true then
spreads ...extraRoomInfo which allows hooks to override it; to make the marker
non-overridable, move the spread before the explicit property so the final value
wins (i.e., use ...extraRoomInfo, _enforceSingleRoom: true) in the object
created in Helper.ts where _enforceSingleRoom and extraRoomInfo are used.

---

Nitpick comments:
In `@apps/meteor/app/livechat/server/lib/Helper.ts`:
- Around line 147-148: Remove the two implementation comments that explain the
"marker field for unique index - only new rooms have this field" and "allows
index creation to succeed even if old duplicates exist" from Helper.ts; instead
document this rationale in the PR description or migration docs and leave the
implementation code free of explanatory comments per the coding guideline "Avoid
code comments in the implementation." Ensure no other inline explanatory
comments remain near the marker field usage so the code contains only necessary
code-level comments (if any).

In `@packages/core-typings/src/IRoom.ts`:
- Around line 313-315: Keep the _enforceSingleRoom?: boolean; field but remove
the two inline implementation comment lines above it; retain the property
declaration exactly as-is (symbol: _enforceSingleRoom) and move the explanatory
text about the marker field and index behaviour out of code into PR/docs context
instead of leaving it in the IRoom definition.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f6b887 and 9b052bd.

📒 Files selected for processing (3)
  • apps/meteor/app/livechat/server/lib/Helper.ts
  • packages/core-typings/src/IRoom.ts
  • packages/models/src/models/LivechatRooms.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: cubic · AI code reviewer
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • packages/models/src/models/LivechatRooms.ts
  • packages/core-typings/src/IRoom.ts
  • apps/meteor/app/livechat/server/lib/Helper.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 35995
File: apps/meteor/app/api/server/v1/rooms.ts:1107-1112
Timestamp: 2026-02-23T17:53:18.785Z
Learning: In Rocket.Chat PR reviews, maintain strict scope boundaries—when a PR is focused on a specific endpoint (e.g., rooms.favorite), avoid reviewing or suggesting changes to other endpoints that were incidentally refactored (e.g., rooms.invite) unless explicitly requested by maintainers.
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Applied to files:

  • packages/models/src/models/LivechatRooms.ts
  • packages/core-typings/src/IRoom.ts
  • apps/meteor/app/livechat/server/lib/Helper.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Applied to files:

  • packages/models/src/models/LivechatRooms.ts
  • packages/core-typings/src/IRoom.ts
  • apps/meteor/app/livechat/server/lib/Helper.ts
📚 Learning: 2025-11-27T17:56:26.050Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37557
File: apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx:115-116
Timestamp: 2025-11-27T17:56:26.050Z
Learning: In Rocket.Chat, the GET /v1/abac/rooms endpoint (implemented in ee/packages/abac/src/index.ts) only returns rooms where abacAttributes exists and is not an empty array (query: { abacAttributes: { $exists: true, $ne: [] } }). Therefore, in components consuming this endpoint (like AdminABACRooms.tsx), room.abacAttributes is guaranteed to be defined for all returned rooms, and optional chaining before calling array methods like .join() is sufficient without additional null coalescing.

Applied to files:

  • packages/core-typings/src/IRoom.ts
  • apps/meteor/app/livechat/server/lib/Helper.ts
📚 Learning: 2025-10-28T16:53:42.761Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37205
File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301
Timestamp: 2025-10-28T16:53:42.761Z
Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.

Applied to files:

  • packages/core-typings/src/IRoom.ts
  • apps/meteor/app/livechat/server/lib/Helper.ts
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.

Applied to files:

  • apps/meteor/app/livechat/server/lib/Helper.ts
🔇 Additional comments (1)
packages/models/src/models/LivechatRooms.ts (1)

80-89: Partial unique index definition looks correct for the intended rollout.

This index cleanly enforces one open room per visitor token for marked rooms without forcing immediate cleanup of legacy duplicates.

@ricardogarim ricardogarim force-pushed the fix/room-creation-livechat branch from 7dbb881 to eef26db Compare March 13, 2026 11:56
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/meteor/app/livechat/server/lib/Helper.ts (1)

148-149: Remove inline implementation comments in this block.

Line 148 and Line 149 add explanatory comments in implementation code; keep this rationale in PR/ADR/tests and leave the runtime object concise.

Proposed cleanup
-		// marker field for unique index - only new rooms have this field (see `#39087`)
-		// allows index creation to succeed even if old duplicates exist
 		_enforceSingleRoom: true,

As per coding guidelines: "Avoid code comments in the implementation".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/livechat/server/lib/Helper.ts` around lines 148 - 149, In
Helper.ts remove the two inline explanatory comment lines that read "marker
field for unique index - only new rooms have this field (see `#39087`)" and
"allows index creation to succeed even if old duplicates exist" so the runtime
object remains concise; keep the rationale in the PR/ADR/tests instead and do
not change surrounding code or behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/meteor/app/livechat/server/lib/Helper.ts`:
- Around line 148-149: In Helper.ts remove the two inline explanatory comment
lines that read "marker field for unique index - only new rooms have this field
(see `#39087`)" and "allows index creation to succeed even if old duplicates
exist" so the runtime object remains concise; keep the rationale in the
PR/ADR/tests instead and do not change surrounding code or behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bae8908b-775d-4ee4-933d-ac10e2562c11

📥 Commits

Reviewing files that changed from the base of the PR and between 9b052bd and eef26db.

📒 Files selected for processing (1)
  • apps/meteor/app/livechat/server/lib/Helper.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/app/livechat/server/lib/Helper.ts
🧠 Learnings (14)
📓 Common learnings
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 35995
File: apps/meteor/app/api/server/v1/rooms.ts:1107-1112
Timestamp: 2026-02-23T17:53:18.785Z
Learning: In Rocket.Chat PR reviews, maintain strict scope boundaries—when a PR is focused on a specific endpoint (e.g., rooms.favorite), avoid reviewing or suggesting changes to other endpoints that were incidentally refactored (e.g., rooms.invite) unless explicitly requested by maintainers.
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 39545
File: apps/meteor/client/views/room/body/hooks/useHasNewMessages.ts:59-61
Timestamp: 2026-03-11T22:04:20.529Z
Learning: In `apps/meteor/client/views/room/body/hooks/useHasNewMessages.ts`, the `msg.u._id === uid` early-return in the `streamNewMessage` handler is intentional: the "New messages" indicator is designed to notify about messages from other users only. Self-sent messages — including those sent from a different session/device — are always skipped, by design. Do not flag this as a multi-session regression.
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39414
File: apps/meteor/app/api/server/v1/rooms.ts:1241-1297
Timestamp: 2026-03-10T08:13:52.153Z
Learning: In the RocketChat/Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1/rooms.ts, the pattern `ajv.compile<void>({...})` is intentionally used for the 200 response schema even when the endpoint returns `{ success: true }`. This is an established convention across all migrated endpoints (rooms.leave, rooms.favorite, rooms.delete, rooms.muteUser, rooms.unmuteUser). Do not flag this as a type mismatch during reviews of these migration PRs.
Learnt from: Harxhit
Repo: RocketChat/Rocket.Chat PR: 39476
File: apps/meteor/server/methods/addAllUserToRoom.ts:0-0
Timestamp: 2026-03-09T18:39:21.178Z
Learning: In apps/meteor/server/methods/addAllUserToRoom.ts, the implementation uses a single cursor pass (Users.find(userFilter).batchSize(100)) that collects both the full user objects (collectedUsers: IUser[]) and their usernames (usernames: string[]) in one iteration. `beforeAddUserToRoom` is then called once with the full usernames batch (preserving batch-validation semantics), and the subsequent subscription/message processing loop iterates over the same stable `collectedUsers` array — no second DB query is made. This avoids any race condition between validation and processing while preserving the original batch-validation behavior.
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 39535
File: apps/meteor/app/apps/server/bridges/livechat.ts:249-249
Timestamp: 2026-03-11T16:46:55.955Z
Learning: In `apps/meteor/app/apps/server/bridges/livechat.ts`, `createVisitor()` intentionally does not propagate `externalIds` to `registerData`. This is by design: the method is deprecated (JSDoc: `deprecated Use createAndReturnVisitor instead. Note: This method does not support externalIds.`) to push callers toward `createAndReturnVisitor()`, which does support `externalIds`. Do not flag the missing `externalIds` field in `createVisitor()` as a bug.
Learnt from: dougfabris
Repo: RocketChat/Rocket.Chat PR: 39425
File: apps/meteor/app/api/server/v1/rooms.ts:294-296
Timestamp: 2026-03-11T18:15:53.272Z
Learning: In Rocket.Chat's `rooms.mediaConfirm/:rid/:fileId` endpoint (apps/meteor/app/api/server/v1/rooms.ts), updating `file.name` from `bodyParams.fileName` without updating `file.path` is intentionally safe. The file path is keyed by `_id` (not by filename), so the stored path remains valid regardless of a rename. `file.name` only affects the display name in the message attachment; do not flag this as a path-divergence issue.
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37205
File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301
Timestamp: 2025-10-28T16:53:42.761Z
Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37205
File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301
Timestamp: 2025-10-28T16:53:42.761Z
Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.
📚 Learning: 2026-03-11T22:04:20.529Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 39545
File: apps/meteor/client/views/room/body/hooks/useHasNewMessages.ts:59-61
Timestamp: 2026-03-11T22:04:20.529Z
Learning: In `apps/meteor/client/views/room/body/hooks/useHasNewMessages.ts`, the `msg.u._id === uid` early-return in the `streamNewMessage` handler is intentional: the "New messages" indicator is designed to notify about messages from other users only. Self-sent messages — including those sent from a different session/device — are always skipped, by design. Do not flag this as a multi-session regression.

Applied to files:

  • apps/meteor/app/livechat/server/lib/Helper.ts
📚 Learning: 2026-03-11T16:46:55.955Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 39535
File: apps/meteor/app/apps/server/bridges/livechat.ts:249-249
Timestamp: 2026-03-11T16:46:55.955Z
Learning: In `apps/meteor/app/apps/server/bridges/livechat.ts`, `createVisitor()` intentionally does not propagate `externalIds` to `registerData`. This is by design: the method is deprecated (JSDoc: `deprecated Use createAndReturnVisitor instead. Note: This method does not support externalIds.`) to push callers toward `createAndReturnVisitor()`, which does support `externalIds`. Do not flag the missing `externalIds` field in `createVisitor()` as a bug.

Applied to files:

  • apps/meteor/app/livechat/server/lib/Helper.ts
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.

Applied to files:

  • apps/meteor/app/livechat/server/lib/Helper.ts
📚 Learning: 2026-03-03T11:11:48.541Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39230
File: apps/meteor/app/api/server/v1/chat.ts:214-222
Timestamp: 2026-03-03T11:11:48.541Z
Learning: In apps/meteor/server/lib/moderation/reportMessage.ts, the reportMessage function validates that description is not empty or whitespace-only with `if (!description.trim())`. When migrating the chat.reportMessage endpoint to OpenAPI, adding minLength validation to the schema preserves this existing behavior.

Applied to files:

  • apps/meteor/app/livechat/server/lib/Helper.ts
📚 Learning: 2026-03-10T08:13:52.153Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39414
File: apps/meteor/app/api/server/v1/rooms.ts:1241-1297
Timestamp: 2026-03-10T08:13:52.153Z
Learning: In the RocketChat/Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1/rooms.ts, the pattern `ajv.compile<void>({...})` is intentionally used for the 200 response schema even when the endpoint returns `{ success: true }`. This is an established convention across all migrated endpoints (rooms.leave, rooms.favorite, rooms.delete, rooms.muteUser, rooms.unmuteUser). Do not flag this as a type mismatch during reviews of these migration PRs.

Applied to files:

  • apps/meteor/app/livechat/server/lib/Helper.ts
📚 Learning: 2026-03-09T18:39:21.178Z
Learnt from: Harxhit
Repo: RocketChat/Rocket.Chat PR: 39476
File: apps/meteor/server/methods/addAllUserToRoom.ts:0-0
Timestamp: 2026-03-09T18:39:21.178Z
Learning: In apps/meteor/server/methods/addAllUserToRoom.ts, the implementation uses a single cursor pass (Users.find(userFilter).batchSize(100)) that collects both the full user objects (collectedUsers: IUser[]) and their usernames (usernames: string[]) in one iteration. `beforeAddUserToRoom` is then called once with the full usernames batch (preserving batch-validation semantics), and the subsequent subscription/message processing loop iterates over the same stable `collectedUsers` array — no second DB query is made. This avoids any race condition between validation and processing while preserving the original batch-validation behavior.

Applied to files:

  • apps/meteor/app/livechat/server/lib/Helper.ts
📚 Learning: 2025-10-28T16:53:42.761Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37205
File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301
Timestamp: 2025-10-28T16:53:42.761Z
Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.

Applied to files:

  • apps/meteor/app/livechat/server/lib/Helper.ts
📚 Learning: 2026-03-12T10:26:26.697Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39340
File: apps/meteor/app/api/server/v1/im.ts:1349-1398
Timestamp: 2026-03-12T10:26:26.697Z
Learning: In `apps/meteor/app/api/server/v1/im.ts` (PR `#39340`), the `DmEndpoints` type intentionally includes temporary stub entries for `/v1/im.kick`, `/v1/dm.kick`, `/v1/im.leave`, and `/v1/dm.leave` (using `DmKickProps` and `DmLeaveProps`) even though no route handlers exist for them yet. These stubs were added to preserve type compatibility after removing the original `DmLeaveProps` and related files. They are planned for cleanup in a follow-up PR. Do not flag these as missing implementations when reviewing this file until the follow-up is merged.

Applied to files:

  • apps/meteor/app/livechat/server/lib/Helper.ts
📚 Learning: 2026-03-11T18:15:53.272Z
Learnt from: dougfabris
Repo: RocketChat/Rocket.Chat PR: 39425
File: apps/meteor/app/api/server/v1/rooms.ts:294-296
Timestamp: 2026-03-11T18:15:53.272Z
Learning: In Rocket.Chat's `rooms.mediaConfirm/:rid/:fileId` endpoint (apps/meteor/app/api/server/v1/rooms.ts), updating `file.name` from `bodyParams.fileName` without updating `file.path` is intentionally safe. The file path is keyed by `_id` (not by filename), so the stored path remains valid regardless of a rename. `file.name` only affects the display name in the message attachment; do not flag this as a path-divergence issue.

Applied to files:

  • apps/meteor/app/livechat/server/lib/Helper.ts
📚 Learning: 2025-11-27T17:56:26.050Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37557
File: apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx:115-116
Timestamp: 2025-11-27T17:56:26.050Z
Learning: In Rocket.Chat, the GET /v1/abac/rooms endpoint (implemented in ee/packages/abac/src/index.ts) only returns rooms where abacAttributes exists and is not an empty array (query: { abacAttributes: { $exists: true, $ne: [] } }). Therefore, in components consuming this endpoint (like AdminABACRooms.tsx), room.abacAttributes is guaranteed to be defined for all returned rooms, and optional chaining before calling array methods like .join() is sufficient without additional null coalescing.

Applied to files:

  • apps/meteor/app/livechat/server/lib/Helper.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: UserBridge.doGetUserRoomIds in packages/apps-engine/src/server/bridges/UserBridge.ts has a bug where it implicitly returns undefined when the app lacks read permission (missing return statement in the else case of the permission check).

Applied to files:

  • apps/meteor/app/livechat/server/lib/Helper.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Applied to files:

  • apps/meteor/app/livechat/server/lib/Helper.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Applied to files:

  • apps/meteor/app/livechat/server/lib/Helper.ts

@ricardogarim ricardogarim added the stat: QA assured Means it has been tested and approved by a company insider label Mar 17, 2026
@ricardogarim ricardogarim added this to the 8.3.0 milestone Mar 17, 2026
@dionisio-bot dionisio-bot bot added the stat: ready to merge PR tested and approved waiting for merge label Mar 17, 2026
@dionisio-bot dionisio-bot bot added this pull request to the merge queue Mar 17, 2026
@sampaiodiego sampaiodiego removed this pull request from the merge queue due to a manual request Mar 17, 2026
@sampaiodiego sampaiodiego merged commit cd2fc20 into develop Mar 17, 2026
80 of 82 checks passed
@sampaiodiego sampaiodiego deleted the fix/room-creation-livechat branch March 17, 2026 16:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stat: QA assured Means it has been tested and approved by a company insider stat: ready to merge PR tested and approved waiting for merge type: bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants