Skip to content

Conversation

@KevLehman
Copy link
Member

@KevLehman KevLehman commented Feb 10, 2026

Proposed changes (including videos or screenshots)

Issue(s)

https://rocketchat.atlassian.net/browse/CORE-1803

Steps to test or reproduce

Further comments

Summary by CodeRabbit

  • New Features

    • Added high-contrast theme mode option for enhanced accessibility, providing improved visual clarity for users with color vision deficiencies.
  • Improvements

    • Code quality enhancements and internal refactoring across multiple services and components to improve stability.
    • Enhanced reliability and improved error handling in asynchronous operations throughout the platform.

Note: the no-misused-promises is disabled in some ui packages as the components being used (and imported from other packages) do not accept the Promise<void> signature.
Note 2 on lib downgrade: 2 packages had es2024. This lib is apparently newer than our ESLint parser (someday we'll update to eslint 9) so in order to apply the rule, i needed to downgrade a year. Hopefully nothing game-changing happened between 23/24

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Feb 10, 2026

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

@changeset-bot
Copy link

changeset-bot bot commented Feb 10, 2026

⚠️ No Changeset found

Latest commit: 0cc0d77

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 10, 2026

Walkthrough

This pull request systematically adds void prefixes to intentionally unhandled promise-returning calls across the codebase and updates ESLint configurations to enforce promise-handling rules. The changes apply consistent fire-and-forget patterns to async initialization functions and callback handlers while modifying TypeScript configurations to support these patterns.

Changes

Cohort / File(s) Summary
ESLint Configuration
apps/meteor/.eslintrc.json, packages/eslint-config/standard/index.js, packages/fuselage-ui-kit/.eslintrc.json, packages/livechat/.eslintrc.json, packages/ui-client/.eslintrc.json, packages/ui-contexts/.eslintrc.json, packages/ui-voip/.eslintrc.json
Adds or disables TypeScript ESLint promise-handling rules (no-misused-promises, no-floating-promises) across packages with override configurations for TS/TSX files.
Service Initialization IIFEs
ee/apps/account-service/src/service.ts, ee/apps/authorization-service/src/service.ts, ee/apps/ddp-streamer/src/service.ts, ee/apps/omnichannel-transcript/src/service.ts, ee/apps/presence-service/src/service.ts, ee/apps/queue-worker/src/service.ts, packages/ddp-client/__examples__/simple.ts, packages/livechat/src/entry.ts
Wraps top-level async IIFEs with void to explicitly discard returned promises from service initialization.
Async Call Fire-and-Forget Patterns
apps/meteor/.scripts/run-ha.ts, ee/apps/ddp-streamer/src/Client.ts, ee/apps/ddp-streamer/src/DDPStreamer.ts, ee/packages/media-calls/src/internal/agents/CallSignalProcessor.ts, ee/packages/media-calls/src/sip/Session.ts, ee/packages/media-calls/src/sip/providers/IncomingSipCall.ts, ee/packages/media-calls/src/sip/providers/OutgoingSipCall.ts, ee/packages/omnichannel-services/src/OmnichannelTranscript.ts, ee/packages/presence/src/Presence.ts, ee/packages/federation-matrix/src/events/index.ts, packages/agenda/src/Agenda.ts, packages/core-services/src/LocalBroker.ts, packages/ddp-client/src/ClientStream.ts, packages/ddp-client/src/Connection.ts, packages/ddp-client/src/DDPSDK.ts, packages/instance-status/src/index.ts, packages/media-signaling/src/lib/Call.ts
Adds void prefix to promise-returning method calls in event handlers, state updates, and utility functions to mark them as intentionally unhandled.
UI Component Element Handlers
packages/fuselage-ui-kit/src/blocks/VideoConferenceBlock/VideoConferenceBlock.tsx, packages/fuselage-ui-kit/src/elements/ButtonElement.tsx, packages/fuselage-ui-kit/src/elements/ChannelsSelectElement/ChannelsSelectElement.tsx, packages/fuselage-ui-kit/src/elements/ChannelsSelectElement/MultiChannelsSelectElement.tsx, packages/fuselage-ui-kit/src/elements/IconButtonElement.tsx, packages/fuselage-ui-kit/src/elements/MultiStaticSelectElement.tsx, packages/fuselage-ui-kit/src/elements/OverflowElement.tsx, packages/fuselage-ui-kit/src/elements/StaticSelectElement.tsx, packages/fuselage-ui-kit/src/elements/TabElement.tsx, packages/fuselage-ui-kit/src/elements/UsersSelectElement/MultiUsersSelectElement.tsx, packages/fuselage-ui-kit/src/elements/UsersSelectElement/UsersSelectElement.tsx
Wraps action callback invocations with void to discard returned promise values in UI event handlers.
LiveChat Package Updates
packages/livechat/src/components/App/App.tsx, packages/livechat/src/hooks/livechatRoomSubscriptionHooks.ts, packages/livechat/src/hooks/useRoomMessagesSubscription.ts, packages/livechat/src/lib/connection.ts, packages/livechat/src/lib/hooks.ts, packages/livechat/src/lib/transcript.ts
Adds void prefixes to async method calls and state update invocations across subscription hooks, connection management, and utility functions.
TypeScript Build Configuration
packages/ddp-client/tsconfig.build.json, packages/ddp-client/tsconfig.json, packages/ddp-client/package.json, ee/packages/federation-matrix/tsconfig.build.json, ee/packages/federation-matrix/tsconfig.json, packages/i18n/tsconfig.json
Introduces dedicated build TypeScript configs with explicit compiler options, updates include/exclude patterns, and modifies build scripts to reference new configs.
Mock Provider & Theme Updates
packages/mock-providers/src/MockedAppRootBuilder.tsx, ee/packages/ui-theming/src/hooks/useThemeMode.ts
Changes mock server methods to throw synchronously instead of returning rejected promises; updates useThemeMode type signatures and adds high-contrast theme option.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 Promises tamed with void's gentle hand,
Fire-and-forget across the land,
ESLint rules now standing tall,
Async handlers answer the call,
Hop, hop—no more warnings to fight!

🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes substantial out-of-scope changes: systematic void operator additions throughout 40+ files that suppress promise warnings but don't enforce the eslint rules themselves, contradicting the stated objective of standardizing eslint rules. Remove void operator additions that work around eslint rules rather than enforce them. If exceptions are needed, handle them explicitly in eslintrc overrides instead of suppressing warnings throughout the codebase.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'chore: Standardize eslint typescript rules' directly and clearly summarizes the main change: standardizing ESLint TypeScript rules across the repository.
Linked Issues check ✅ Passed The PR successfully addresses CORE-1803 by applying TypeScript ESLint rules (no-misused-promises and no-floating-promises) consistently across packages via eslintrc updates and code modifications with void operators.

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


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.

@KevLehman KevLehman changed the title use eslint typescript rules chore: Standardize eslint typescript rules Feb 10, 2026
@codecov
Copy link

codecov bot commented Feb 10, 2026

Codecov Report

❌ Patch coverage is 10.00000% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.44%. Comparing base (8f5df55) to head (0cc0d77).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #38584      +/-   ##
===========================================
- Coverage    70.45%   70.44%   -0.02%     
===========================================
  Files         3174     3174              
  Lines       111003   111003              
  Branches     19991    19988       -3     
===========================================
- Hits         78204    78192      -12     
- Misses       30756    30764       +8     
- Partials      2043     2047       +4     
Flag Coverage Δ
e2e 60.46% <ø> (+0.06%) ⬆️
e2e-api 47.73% <ø> (ø)
unit 71.40% <10.00%> (-0.05%) ⬇️

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.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

📦 Docker Image Size Report

➡️ Changes

Service Current Baseline Change Percent
sum of all images 0B 0B 0B
account-service 0B 0B 0B
authorization-service 0B 0B 0B
ddp-streamer-service 0B 0B 0B
omnichannel-transcript-service 0B 0B 0B
presence-service 0B 0B 0B
queue-worker-service 0B 0B 0B
rocketchat 0B 0B 0B

📊 Historical Trend

---
config:
  theme: "dark"
  xyChart:
    width: 900
    height: 400
---
xychart
  title "Image Size Evolution by Service (Last 30 Days + This PR)"
  x-axis ["11/18 22:53", "11/19 23:02", "11/21 16:49", "11/24 17:34", "11/27 22:32", "11/28 19:05", "12/01 23:01", "12/02 21:57", "12/03 21:00", "12/04 18:17", "12/05 21:56", "12/08 20:15", "12/09 22:17", "12/10 23:26", "12/11 21:56", "12/12 22:45", "12/13 01:34", "12/15 22:31", "12/16 22:18", "12/17 21:04", "12/18 23:12", "12/19 23:27", "12/20 21:03", "12/22 18:54", "12/23 16:16", "12/24 19:38", "12/25 17:51", "12/26 13:18", "12/29 19:01", "12/30 20:52", "02/11 18:18 (PR)"]
  y-axis "Size (GB)" 0 --> 0.5
  line "account-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.00]
  line "authorization-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.00]
  line "ddp-streamer-service" [0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.00]
  line "omnichannel-transcript-service" [0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.00]
  line "presence-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.00]
  line "queue-worker-service" [0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.00]
  line "rocketchat" [0.35, 0.35, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.00]
Loading

Statistics (last 30 days):

  • 📊 Average: 1.5GiB
  • ⬇️ Minimum: 1.4GiB
  • ⬆️ Maximum: 1.6GiB
  • 🎯 Current PR: 0B
ℹ️ About this report

This report compares Docker image sizes from this build against the develop baseline.

  • Tag: pr-38584
  • Baseline: develop
  • Timestamp: 2026-02-11 18:18:39 UTC
  • Historical data points: 30

Updated: Wed, 11 Feb 2026 18:18:40 GMT

@KevLehman KevLehman marked this pull request as ready for review February 10, 2026 17:46
@KevLehman KevLehman requested review from a team as code owners February 10, 2026 17:46
@KevLehman KevLehman added this to the 8.2.0 milestone Feb 10, 2026
@KevLehman KevLehman added the stat: QA assured Means it has been tested and approved by a company insider label Feb 10, 2026
@dionisio-bot dionisio-bot bot removed the stat: QA assured Means it has been tested and approved by a company insider label Feb 10, 2026
Copy link
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 35 files

Copy link
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: 12

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
ee/apps/queue-worker/src/service.ts (1)

19-19: ⚠️ Potential issue | 🟡 Minor

Pre-existing typo in comment: registeredpackagferegistered package.

packages/instance-status/src/index.ts (1)

31-56: ⚠️ Potential issue | 🟠 Major

Race condition: dropIndex and createIndex may execute concurrently.

When an existing index has a mismatched expireAfterSeconds, line 39 fires dropIndex without awaiting, then some() returns false, causing line 49 to fire createIndex immediately. These two operations can overlap, and MongoDB may reject the createIndex if the old index hasn't been fully dropped yet. Since both promises are void-ed, the error is silently lost, leaving the collection without a proper TTL index.

Previously these calls were presumably returned/awaited within the .then() chain, maintaining sequential execution.

Suggested fix: keep the index operations awaited within the chain
 let createIndexes = async () => {
-	await InstanceStatusModel.col
-		.indexes()
-		.catch(() => [])
-		.then((result) =>
-			result.some((index) => {
-				if (index.key && index.key._updatedAt === 1) {
-					if (index.expireAfterSeconds !== indexExpire && index.name) {
-						void InstanceStatusModel.col.dropIndex(index.name);
-						return false;
-					}
-					return true;
-				}
-				return false;
-			}),
-		)
-		.then((created) => {
-			if (!created) {
-				void InstanceStatusModel.col.createIndex({ _updatedAt: 1 }, { expireAfterSeconds: indexExpire });
-			}
-		});
+	const existingIndexes = await InstanceStatusModel.col.indexes().catch(() => []);
+	const hasValidIndex = existingIndexes.some((index) => {
+		if (index.key && index.key._updatedAt === 1) {
+			return index.expireAfterSeconds === indexExpire;
+		}
+		return false;
+	});
+
+	const staleIndex = existingIndexes.find(
+		(index) => index.key && index.key._updatedAt === 1 && index.expireAfterSeconds !== indexExpire && index.name,
+	);
+	if (staleIndex?.name) {
+		await InstanceStatusModel.col.dropIndex(staleIndex.name);
+	}
+
+	if (!hasValidIndex) {
+		await InstanceStatusModel.col.createIndex({ _updatedAt: 1 }, { expireAfterSeconds: indexExpire });
+	}

 	createIndexes = async () => {
 		// noop
 	};
 };
ee/packages/ui-theming/src/hooks/useThemeMode.ts (1)

11-25: ⚠️ Potential issue | 🟡 Minor

Return type of setTheme is inaccurate — the returned function yields a Promise, not void.

Line 11 declares the setter as (value: ThemeMode) => () => void, but the updaters (line 17) now explicitly return ReturnType<typeof saveUserPreferences> (a Promise). Callers invoking the returned thunk receive an unhandled promise. This mismatch was likely pre-existing but is now surfaced by the type change on line 17.

Suggested type alignment
-export const useThemeMode = (): [ThemeMode, (value: ThemeMode) => () => void, Themes] => {
+export const useThemeMode = (): [ThemeMode, (value: ThemeMode) => () => ReturnType<typeof saveUserPreferences>, Themes] => {

Note: saveUserPreferences is scoped inside the hook, so you may need to extract or inline the return type (e.g., () => Promise<void>). Alternatively, if callers intentionally discard the promise, keep () => void but add void at call sites.

packages/agenda/src/Agenda.ts (1)

180-188: ⚠️ Potential issue | 🟡 Minor

void this.dbInit(collection) silently detaches index-creation errors from await database().

database() is public async, so external callers can await it. By voiding dbInit, any index-creation failure inside dbInit will not propagate to callers of database(). The 'error' event is still emitted, but callers awaiting database() will see it resolve successfully even when dbInit fails.

If this is intentional (relying solely on the event pattern), consider documenting it. Otherwise, await would preserve error propagation:

Suggested fix
-			void this.dbInit(collection);
+			await this.dbInit(collection);
🤖 Fix all issues with AI agents
In `@ee/apps/ddp-streamer/src/DDPStreamer.ts`:
- Around line 185-215: Presence.removeConnection calls in the LOGGEDOUT and
DISCONNECTED handlers are fire-and-forget so failures are swallowed; update
those handlers (the server.on callbacks for DDP_EVENTS.LOGGEDOUT and
DDP_EVENTS.DISCONNECTED) to handle errors from Presence.removeConnection by
either awaiting the promise or attaching a .catch(...) that logs the failure
(include context like userId, connection.id and nodeID) and ensure
updateConnections remains called as appropriate; reference the
Presence.removeConnection(...) calls in those handlers and add proper error
logging/handling consistent with how Presence.newConnection is awaited in the
LOGGED handler.

In `@ee/apps/omnichannel-transcript/src/service.ts`:
- Line 12: The top-level IIFE `void (async () => { ... })` in service.ts can
produce unhandled promise rejections; modify this bootstrap to append a
`.catch(...)` to the IIFE (or register `process.on('unhandledRejection', ...)`)
that logs the error (use the existing logger or `console.error`) and calls
`process.exit(1)` so any rejected await inside the async IIFE (e.g., DB
connection failures) is logged and the process exits cleanly.

In `@ee/apps/presence-service/src/service.ts`:
- Line 9: The top-level IIFE using "void (async () => { ... })()" swallows
startup rejections; update the entry to surface failures by removing the leading
void and handling rejections: invoke the async entry function and attach a
.catch handler that logs the error (e.g., via logger.error or console.error) and
calls process.exit(1). Ensure the error handler covers failures from
getConnection(), api.start(), and any awaited calls inside the IIFE so the
process crashes on fatal startup errors.

In `@ee/apps/queue-worker/src/service.ts`:
- Line 10: The startup uses an async IIFE prefixed with "void (async () => {"
which swallows thrown errors; replace this pattern so startup failures are not
ignored by invoking the IIFE and catching errors (e.g., call the IIFE with ())
and add a .catch handler that logs the error and calls process.exit(1); locate
the async IIFE started with "void (async () => {" in service.ts and change its
invocation to ensure any thrown exceptions are handled and cause the process to
exit.

In `@ee/packages/media-calls/src/sip/providers/IncomingSipCall.ts`:
- Line 172: The call to calleeAgent.onRemoteDescriptionChanged(this.call._id,
negotiationId) is currently void-ed which swallows rejections and prevents the
surrounding try/catch from performing cleanup (sending the SIP error response,
removing the negotiation, and hanging up); change this so the promise rejection
is handled: either await calleeAgent.onRemoteDescriptionChanged(this.call._id,
negotiationId) inside the existing try block so failures flow to the catch, or
if you must keep it non-blocking, attach a .catch that invokes the same recovery
steps (call sendSipErrorResponse with the same args, remove the negotiation from
the negotiations map with negotiations.delete(negotiationId), and call
this.call.hangup()) and rethrow or log appropriately so the main error-recovery
logic still runs.

In `@ee/packages/omnichannel-services/src/OmnichannelTranscript.ts`:
- Around line 378-380: The fire-and-forget call to pdfFailed is creating a risk
of unhandled promise rejections because pdfFailed performs async I/O
(createDirectMessage, sendMessage) and has no internal try/catch; replace the
current void this.pdfFailed({ details, e: error as Error, i18n }); with a
fire-and-forget invocation that attaches a .catch(...) to handle/log any error
(e.g. this.pdfFailed(...).catch(err => processLogger?.error('pdfFailed error',
err)) ) so failures inside pdfFailed are swallowed/logged; alternatively make
the call consistent with the other site that awaits pdfFailed by awaiting it if
the surrounding flow permits. Ensure references to pdfFailed,
createDirectMessage and sendMessage are preserved when adding the .catch or
switching to await.

In `@ee/packages/presence/src/Presence.ts`:
- Line 54: The call to validateAvailability on the Presence class is currently
invoked with "void this.validateAvailability()", which swallows promise
rejections from validateAvailability (which writes via
Settings.updateValueById). Change the invocation to properly handle errors:
either await this.validateAvailability() inside an async function with try/catch
that logs failures, or chain this.validateAvailability().catch(err => /* log
error with context */) so any DB/save errors are logged; ensure the log includes
context like "Presence.validateAvailability" and the error object.

In `@packages/agenda/src/Agenda.ts`:
- Line 473: The update path currently calls this._processDbResult(job, result)
with void which swallows its promise and can create unhandled rejections; change
that call to return the promise instead so its rejection is propagated
consistent with the other save paths that return this._processDbResult (see
_saveSingleJob, _saveUniqueJob, _saveNewJob and the call site result && void
this._processDbResult(job, result)). Ensure the method containing that line
returns the result of this._processDbResult(job, result) when result is truthy.

In `@packages/core-services/src/LocalBroker.ts`:
- Line 97: The call to instance.created() is awaited with void and so any
rejection is swallowed; change it to handle errors by attaching a .catch that
logs the error via the broker/logger and prevents leaving a half-initialized
service registered — e.g., call instance.created().catch(err => {
logger.error('service created failed', { service: instance.name, err }); /*
optionally remove from this.services or avoid calling registerService */ }); and
ensure the code that registers the service (the registerService or
this.services.set path) only runs on successful creation.

In `@packages/ddp-client/.eslintrc.json`:
- Around line 26-37: The override currently sets "parserOptions": { "project":
null } which disables all type-aware ESLint rules (not just the two promise
rules) — remove the parserOptions block (or set "project": true) from the
override so the base `@rocket.chat/eslint-config`'s type-aware override can apply,
and keep only the explicit rule disables for
"@typescript-eslint/no-misused-promises" and
"@typescript-eslint/no-floating-promises" under "rules".

In `@packages/instance-status/src/index.ts`:
- Around line 58-59: registerInstance currently fire-and-forgets createIndexes
by calling void createIndexes(), which can start registration/heartbeat before
the TTL index exists and can silence index creation failures; change this to
await createIndexes() inside registerInstance and handle errors (catch and log
or rethrow) so index creation failures surface and prevent starting the
heartbeat/registration flow until indexes are guaranteed; reference the
registerInstance function and the createIndexes function and ensure any
heartbeat/startHeartbeat logic only runs after the awaited createIndexes
completes successfully.

In `@packages/ui-voip/.eslintrc.json`:
- Around line 4-15: The override in .eslintrc.json currently sets
"parserOptions.project": null and turns off
"@typescript-eslint/no-misused-promises" and
"@typescript-eslint/no-floating-promises" for all "**/*.ts" and "**/*.tsx",
which weakens TypeScript linting; change this by restoring type-aware checks and
narrowing or softening the rules: set "parserOptions.project" to the appropriate
tsconfig (or remove the override so type-aware rules apply), and instead of
"off" change "@typescript-eslint/no-misused-promises" and
"@typescript-eslint/no-floating-promises" to "warn" or move them into a
file-scoped override for only the problematic files; update the override’s
"files" glob to target the specific exceptions rather than all TS/TSX files so
the rest of the repo inherits the standardized rules.
🧹 Nitpick comments (5)
apps/meteor/.scripts/run-ha.ts (1)

87-91: void is correct here for the lint rule, but note these functions aren't actually async.

runMain and runInstance are declared async yet contain no await — they just call synchronous spawn(). The void prefix satisfies no-floating-promises, but if someone later adds actual async work to these functions, rejections will be silently swallowed. For a dev-only script this is low risk, but removing the unnecessary async keyword from both functions would be a cleaner fix.

packages/ddp-client/src/Connection.ts (1)

200-202: Consider adding .catch to prevent unhandled rejection on reconnect failure.

reconnect() can reject (e.g., Line 113: "Connection in progress"). With void, that rejection is unhandled. A defensive .catch keeps the retry loop clean:

-					void this.reconnect();
+					void this.reconnect().catch(() => undefined);
ee/packages/media-calls/src/internal/agents/CallSignalProcessor.ts (1)

266-270: Unhandled rejection risk on onDTMF.

If onDTMF rejects, the promise is unhandled. Since this is intentionally fire-and-forget, add a .catch to suppress:

-		void this.agent.oppositeAgent?.onDTMF(this.call._id, dtmf, duration || 2000);
+		void this.agent.oppositeAgent?.onDTMF(this.call._id, dtmf, duration || 2000).catch((err) => {
+			logger.error({ msg: 'Failed to send DTMF to opposite agent', err });
+		});
packages/ddp-client/src/DDPSDK.ts (1)

115-122: void on reconnect login is acceptable, but a .catch would improve debuggability.

The connected event handler can't propagate a promise, so void is appropriate. However, a silent token-login failure during reconnect could be hard to diagnose. Consider adding a .catch for logging if a logger is available in this context.

packages/i18n/.eslintrc.json (1)

8-17: "project": null disables all type-aware rules, making the explicit rule overrides redundant.

Setting parserOptions.project to null prevents typescript-eslint from performing type-checked linting entirely. The two rule overrides on lines 15–16 are therefore redundant since those rules require type information to function. More importantly, this also silently disables every other type-aware rule (e.g., no-unnecessary-type-assertion, no-unsafe-*, await-thenable, etc.).

If the intent is only to disable the two promise rules, consider pointing project to the package's tsconfig.json and keeping just the rule overrides. If the intent is to skip type-aware linting in this package entirely, the explicit rule lines are unnecessary noise.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7045358 and 8228125.

📒 Files selected for processing (35)
  • apps/meteor/.eslintrc.json
  • apps/meteor/.scripts/run-ha.ts
  • ee/apps/account-service/src/service.ts
  • ee/apps/authorization-service/src/service.ts
  • ee/apps/ddp-streamer/src/Client.ts
  • ee/apps/ddp-streamer/src/DDPStreamer.ts
  • ee/apps/ddp-streamer/src/service.ts
  • ee/apps/omnichannel-transcript/src/service.ts
  • ee/apps/presence-service/src/service.ts
  • ee/apps/queue-worker/src/service.ts
  • ee/packages/federation-matrix/.eslintrc.json
  • ee/packages/media-calls/src/internal/agents/CallSignalProcessor.ts
  • ee/packages/media-calls/src/sip/Session.ts
  • ee/packages/media-calls/src/sip/providers/IncomingSipCall.ts
  • ee/packages/media-calls/src/sip/providers/OutgoingSipCall.ts
  • ee/packages/omnichannel-services/src/OmnichannelTranscript.ts
  • ee/packages/presence/src/Presence.ts
  • ee/packages/ui-theming/src/hooks/useThemeMode.ts
  • packages/agenda/src/Agenda.ts
  • packages/core-services/src/LocalBroker.ts
  • packages/ddp-client/.eslintrc.json
  • packages/ddp-client/src/ClientStream.ts
  • packages/ddp-client/src/Connection.ts
  • packages/ddp-client/src/DDPSDK.ts
  • packages/eslint-config/standard/index.js
  • packages/fuselage-ui-kit/.eslintrc.json
  • packages/i18n/.eslintrc.json
  • packages/instance-status/src/index.ts
  • packages/livechat/.eslintrc.json
  • packages/media-signaling/src/lib/Call.ts
  • packages/mock-providers/src/MockedAppRootBuilder.tsx
  • packages/ui-client/.eslintrc.json
  • packages/ui-contexts/.eslintrc.json
  • packages/ui-kit/.eslintrc.json
  • packages/ui-voip/.eslintrc.json
🧰 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:

  • ee/packages/media-calls/src/sip/providers/OutgoingSipCall.ts
  • ee/apps/ddp-streamer/src/service.ts
  • packages/mock-providers/src/MockedAppRootBuilder.tsx
  • ee/packages/presence/src/Presence.ts
  • packages/instance-status/src/index.ts
  • packages/media-signaling/src/lib/Call.ts
  • ee/packages/ui-theming/src/hooks/useThemeMode.ts
  • packages/agenda/src/Agenda.ts
  • ee/packages/media-calls/src/internal/agents/CallSignalProcessor.ts
  • ee/apps/omnichannel-transcript/src/service.ts
  • ee/apps/authorization-service/src/service.ts
  • packages/ddp-client/src/Connection.ts
  • ee/apps/presence-service/src/service.ts
  • ee/apps/queue-worker/src/service.ts
  • ee/packages/media-calls/src/sip/providers/IncomingSipCall.ts
  • ee/apps/account-service/src/service.ts
  • packages/core-services/src/LocalBroker.ts
  • ee/apps/ddp-streamer/src/Client.ts
  • packages/eslint-config/standard/index.js
  • ee/apps/ddp-streamer/src/DDPStreamer.ts
  • packages/ddp-client/src/DDPSDK.ts
  • packages/ddp-client/src/ClientStream.ts
  • ee/packages/media-calls/src/sip/Session.ts
  • ee/packages/omnichannel-services/src/OmnichannelTranscript.ts
🧠 Learnings (18)
📓 Common learnings
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37547
File: packages/i18n/src/locales/en.i18n.json:634-634
Timestamp: 2025-11-19T12:32:29.696Z
Learning: Repo: RocketChat/Rocket.Chat
Context: i18n workflow
Learning: In this repository, new translation keys should be added to packages/i18n/src/locales/en.i18n.json only; other locale files are populated via the external translation pipeline and/or fall back to English. Do not request adding the same key to all locale files in future reviews.
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to **/*.spec.ts : Use `.spec.ts` extension for test files (e.g., `login.spec.ts`)

Applied to files:

  • packages/fuselage-ui-kit/.eslintrc.json
  • packages/i18n/.eslintrc.json
  • packages/ui-contexts/.eslintrc.json
  • packages/ui-voip/.eslintrc.json
  • packages/ui-kit/.eslintrc.json
  • ee/packages/federation-matrix/.eslintrc.json
  • packages/ui-client/.eslintrc.json
  • packages/livechat/.eslintrc.json
  • packages/ddp-client/.eslintrc.json
  • packages/eslint-config/standard/index.js
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to **/*.{ts,tsx,js} : Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests

Applied to files:

  • packages/fuselage-ui-kit/.eslintrc.json
  • packages/i18n/.eslintrc.json
  • packages/ui-contexts/.eslintrc.json
  • packages/ui-voip/.eslintrc.json
  • packages/ui-kit/.eslintrc.json
  • ee/packages/federation-matrix/.eslintrc.json
  • apps/meteor/.eslintrc.json
  • packages/ui-client/.eslintrc.json
  • packages/livechat/.eslintrc.json
  • packages/ddp-client/.eslintrc.json
  • packages/eslint-config/standard/index.js
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to **/*.{ts,tsx,js} : Avoid code comments in the implementation

Applied to files:

  • packages/fuselage-ui-kit/.eslintrc.json
  • packages/i18n/.eslintrc.json
  • packages/ui-contexts/.eslintrc.json
  • packages/ui-voip/.eslintrc.json
  • packages/ui-kit/.eslintrc.json
  • ee/packages/federation-matrix/.eslintrc.json
  • apps/meteor/.eslintrc.json
  • packages/ui-client/.eslintrc.json
  • packages/ddp-client/.eslintrc.json
  • packages/eslint-config/standard/index.js
📚 Learning: 2025-12-10T21:00:54.909Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37091
File: ee/packages/abac/jest.config.ts:4-7
Timestamp: 2025-12-10T21:00:54.909Z
Learning: Rocket.Chat monorepo: Jest testMatch pattern '<rootDir>/src/**/*.spec.(ts|js|mjs)' is valid in this repo and used across multiple packages (e.g., packages/tools, ee/packages/omnichannel-services). Do not flag it as invalid in future reviews.

Applied to files:

  • packages/fuselage-ui-kit/.eslintrc.json
  • packages/i18n/.eslintrc.json
  • packages/ui-contexts/.eslintrc.json
  • packages/ui-voip/.eslintrc.json
  • packages/ui-kit/.eslintrc.json
  • ee/packages/federation-matrix/.eslintrc.json
  • apps/meteor/.eslintrc.json
  • packages/ui-client/.eslintrc.json
  • packages/livechat/.eslintrc.json
  • packages/ddp-client/.eslintrc.json
  • packages/eslint-config/standard/index.js
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : All test files must be created in `apps/meteor/tests/e2e/` directory

Applied to files:

  • packages/fuselage-ui-kit/.eslintrc.json
  • packages/i18n/.eslintrc.json
  • packages/ui-contexts/.eslintrc.json
  • packages/ui-voip/.eslintrc.json
  • packages/ui-kit/.eslintrc.json
  • ee/packages/federation-matrix/.eslintrc.json
  • apps/meteor/.eslintrc.json
  • packages/ui-client/.eslintrc.json
  • packages/ddp-client/.eslintrc.json
  • packages/eslint-config/standard/index.js
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Group related tests in the same file

Applied to files:

  • packages/fuselage-ui-kit/.eslintrc.json
  • packages/i18n/.eslintrc.json
  • packages/ui-contexts/.eslintrc.json
  • packages/ui-voip/.eslintrc.json
  • packages/ui-kit/.eslintrc.json
  • ee/packages/federation-matrix/.eslintrc.json
  • packages/ui-client/.eslintrc.json
  • packages/ddp-client/.eslintrc.json
  • packages/eslint-config/standard/index.js
📚 Learning: 2025-11-05T21:04:35.787Z
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 37357
File: ee/packages/federation-matrix/src/setup.ts:103-120
Timestamp: 2025-11-05T21:04:35.787Z
Learning: In Rocket.Chat's federation-matrix setup (ee/packages/federation-matrix/src/setup.ts and apps/meteor/ee/server/startup/federation.ts), configureFederationMatrixSettings does not need to be called before setupFederationMatrix. The SDK's init() establishes infrastructure (database, event handlers, APIs) first, and the configuration can be applied later via settings watchers before actual federation events are processed. The config only matters when events actually occur, at which point all infrastructure is already configured.

Applied to files:

  • ee/apps/ddp-streamer/src/service.ts
📚 Learning: 2025-10-06T20:30:45.540Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37152
File: packages/apps-engine/tests/test-data/storage/storage.ts:101-122
Timestamp: 2025-10-06T20:30:45.540Z
Learning: In `packages/apps-engine/tests/test-data/storage/storage.ts`, the stub methods (updatePartialAndReturnDocument, updateStatus, updateSetting, updateAppInfo, updateMarketplaceInfo) intentionally throw "Method not implemented." Tests using these methods must stub them using `SpyOn` from the test library rather than relying on actual implementations.

Applied to files:

  • packages/mock-providers/src/MockedAppRootBuilder.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

  • apps/meteor/.scripts/run-ha.ts
  • apps/meteor/.eslintrc.json
📚 Learning: 2025-09-19T15:15:04.642Z
Learnt from: rodrigok
Repo: RocketChat/Rocket.Chat PR: 36991
File: apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts:219-221
Timestamp: 2025-09-19T15:15:04.642Z
Learning: The Federation_Matrix_homeserver_domain setting in apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts is part of the old federation system and is being deprecated/removed, so configuration issues with this setting should not be flagged for improvement.

Applied to files:

  • ee/packages/federation-matrix/.eslintrc.json
📚 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:

  • packages/agenda/src/Agenda.ts
  • apps/meteor/.eslintrc.json
  • ee/apps/ddp-streamer/src/DDPStreamer.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `expect` matchers for assertions (`toEqual`, `toContain`, `toBeTruthy`, `toHaveLength`, etc.) instead of `assert` statements in Playwright tests

Applied to files:

  • apps/meteor/.eslintrc.json
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/page-objects/**/*.ts : Utilize existing page objects pattern from `apps/meteor/tests/e2e/page-objects/`

Applied to files:

  • apps/meteor/.eslintrc.json
  • packages/eslint-config/standard/index.js
📚 Learning: 2025-10-28T19:39:58.182Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37328
File: packages/ui-voip/src/v2/useTonePlayer.ts:29-30
Timestamp: 2025-10-28T19:39:58.182Z
Learning: In packages/ui-voip/src/v2/useTonePlayer.ts, the DTMF tones generated by TonePlayer are for local auditory feedback to the user only. The actual DTMF signals are transmitted separately through the WebRTC channel. Therefore, filter configurations should prioritize user comfort and audio quality over technical DTMF frequency accuracy.

Applied to files:

  • ee/packages/media-calls/src/internal/agents/CallSignalProcessor.ts
📚 Learning: 2025-09-15T21:34:39.812Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 36717
File: packages/ui-voip/src/providers/useCallSounds.ts:6-21
Timestamp: 2025-09-15T21:34:39.812Z
Learning: The voipSounds methods (playDialer, playRinger, playCallEnded) from useCustomSound return proper offCallbackHandler cleanup functions, not void as some type definitions might suggest.

Applied to files:

  • ee/packages/media-calls/src/internal/agents/CallSignalProcessor.ts
📚 Learning: 2025-11-19T18:20:37.116Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37419
File: apps/meteor/server/services/media-call/service.ts:141-141
Timestamp: 2025-11-19T18:20:37.116Z
Learning: In apps/meteor/server/services/media-call/service.ts, the sendHistoryMessage method should use call.caller.id or call.createdBy?.id as the message author, not call.transferredBy?.id. Even for transferred calls, the message should appear in the DM between the two users who are calling each other, not sent by the person who transferred the call.

Applied to files:

  • ee/packages/media-calls/src/internal/agents/CallSignalProcessor.ts
📚 Learning: 2026-01-27T20:57:56.529Z
Learnt from: nazabucciarelli
Repo: RocketChat/Rocket.Chat PR: 38294
File: apps/meteor/server/hooks/sauMonitorHooks.ts:0-0
Timestamp: 2026-01-27T20:57:56.529Z
Learning: In Rocket.Chat, the `accounts.login` event listened to by DeviceManagementService is only broadcast when running in microservices mode (via DDPStreamer), not in monolith mode. The `Accounts.onLogin` hook in sauMonitorHooks.ts runs in monolith deployments. These are mutually exclusive deployment modes, so there's no duplication of event emissions between these two code paths.

Applied to files:

  • ee/apps/ddp-streamer/src/DDPStreamer.ts
  • packages/ddp-client/src/DDPSDK.ts
🧬 Code graph analysis (2)
packages/mock-providers/src/MockedAppRootBuilder.tsx (1)
apps/meteor/app/lib/server/functions/notifications/email.js (1)
  • lng (25-25)
packages/instance-status/src/index.ts (1)
ee/packages/omnichannel-services/src/QueueWorker.ts (1)
  • createIndexes (54-63)
⏰ 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). (1)
  • GitHub Check: cubic · AI code reviewer
🔇 Additional comments (24)
ee/packages/media-calls/src/sip/Session.ts (1)

149-164: LGTM — void prefix is appropriate here given the event-based error handling.

The connect and error event handlers registered in initializeDrachtio() (lines 124–133) already handle connection outcomes, so discarding the promise with void to satisfy no-floating-promises is the right approach.

apps/meteor/.scripts/run-ha.ts (1)

98-98: LGTM — standard pattern for top-level async invocation.

Using void for the top-level entry point is the conventional way to satisfy no-floating-promises in scripts.

packages/mock-providers/src/MockedAppRootBuilder.tsx (3)

121-129: LGTM — synchronous throws align with existing callEndpoint pattern.

These stubs now throw synchronously instead of returning rejected promises. This matches the pattern already used by callEndpoint (Line 116). Since uploadToEndpoint and callMethod (Lines 119–120) still use Promise.reject, the file now has two stub-failure styles, but this is acceptable for mock/test infrastructure.


650-661: LGTM — void operator correctly silences floating-promise lint warnings.


730-730: LGTM — fire-and-forget i18n.init() properly annotated with void.

packages/eslint-config/standard/index.js (2)

129-165: Overall approach looks good — type-aware promise rules in a dedicated override is the right pattern.

The exclusion list is thorough for test files and build configs, and checksVoidReturn.arguments: false is a pragmatic choice to reduce noise from callback-style APIs.


130-130: The inconsistency is confirmed: .cts and .mts files exist in the repository but are excluded from the second override.

The repo contains 1 .cts file (packages/i18n/src/index.cts) and 5 .mts files (build utilities in packages/i18n/src/scripts/), neither of which match any of the second override's excludedFiles patterns. Confirm whether this exclusion is intentional—for example, if build scripts and CTS wrappers are intentionally treated differently from application TypeScript code.

packages/media-signaling/src/lib/Call.ts (1)

833-833: This pattern is intentional—errors are handled through the event emitter, not promise rejection.

The void usage here aligns with the codebase's error-handling architecture. addNegotiation doesn't throw or reject; instead, errors are propagated via the NegotiationManager.emitter and caught in Call.onNegotiationError, which sends them back to the remote peer. This is consistent with similar code in NegotiationManager.setRemoteDescription, which includes a comment explaining this design: "No need to handle errors here as they are already handled by the 'error' event." Using await would not capture errors any differently and could disrupt the async queueing behavior in processNegotiations.

ee/apps/ddp-streamer/src/service.ts (1)

9-9: LGTM — the unhandledRejection handler (Line 45) provides a safety net for bootstrap failures.

packages/core-services/src/LocalBroker.ts (1)

127-127: Fire-and-forget on broadcastLocal is acceptable here.

broadcastLocal only calls the synchronous this.events.emit(...), so the promise resolves immediately and there's no meaningful rejection to handle.

apps/meteor/.eslintrc.json (1)

142-148: Scoping the promise rule relaxation to client-only code is reasonable.

Disabling no-misused-promises and no-floating-promises only for client/** and ee/client/** is a sensible choice — React event handlers and UI code commonly produce fire-and-forget patterns. Server-side code retains the stricter linting via the broader TS override above.

packages/ddp-client/src/ClientStream.ts (1)

122-125: void on unsubscribe makes the existing fire-and-forget intent explicit.

Since stop() is synchronous and callers can't await it, the void prefix correctly signals intent. The previous code also didn't handle the promise — this just satisfies the linter.

ee/apps/ddp-streamer/src/Client.ts (1)

168-168: LGTM — void correctly signals fire-and-forget intent.

Both callMethod and callSubscribe already chain errors internally via .catch(), so the void prefix accurately communicates that the returned promise is intentionally discarded.

Also applies to: 177-177

ee/apps/authorization-service/src/service.ts (1)

10-10: void makes the already-floating IIFE explicit — fine as a lint fix.

Note that a rejection inside this IIFE (e.g., getConnection() failing) will still surface as an unhandled promise rejection and crash the process, which is likely the desired behavior for a service entry point. No behavioral change here.

ee/packages/media-calls/src/sip/providers/OutgoingSipCall.ts (1)

242-242: void makes the existing fire-and-forget explicit, but note that rejections bypass the surrounding try/catch.

Since the promise is not awaited, any rejection from onRemoteDescriptionChanged will surface as an unhandled promise rejection rather than being caught by the try/catch on line 223. This is pre-existing behavior (unchanged by this PR), but worth noting if onRemoteDescriptionChanged can fail in practice.

packages/livechat/.eslintrc.json (1)

79-104: Setting project: null makes the explicit rule disables redundant.

Both no-misused-promises and no-floating-promises are type-aware rules that require parserOptions.project to function. With project: null, they are already inoperative. The explicit "off" entries are harmless but purely documentary.

This is consistent across all packages in this PR, so presumably intentional for clarity.

packages/ui-client/.eslintrc.json (1)

4-15: Consistent with the repo-wide pattern.

ee/packages/federation-matrix/.eslintrc.json (1)

4-15: Consistent with the repo-wide pattern.

ee/packages/presence/src/Presence.ts (1)

294-305: Fire-and-forget broadcast is appropriate here.

The broadcast method is already typed as returning void, and the optional chaining on this.api?.broadcast means it gracefully no-ops when api is unavailable. The void prefix correctly signals intent.

ee/apps/ddp-streamer/src/DDPStreamer.ts (1)

261-261: Fire-and-forget on registerInstance is acceptable here.

The ping() mechanism (line 92–98) re-registers the instance if the heartbeat finds no matching document, providing a self-healing fallback. Silent failure on initial registration is tolerable.

ee/packages/ui-theming/src/hooks/useThemeMode.ts (1)

21-21: New high-contrast theme mode entry looks correct.

Follows the existing pattern and the useTheme function (line 31) correctly handles the 'high-contrast' case before falling through to 'light'.

packages/agenda/src/Agenda.ts (3)

146-150: LGTM — constructor fire-and-forget is consistent with the _ready event pattern.

The _ready promise (line 144) synchronizes on the 'ready' event emitted by dbInit, so these void calls in the constructor are correct.


833-837: LGTM — fire-and-forget with a complete error-handling chain.

The .catch() ensures the promise never rejects unhandled, and results flow into _processJobResult.


867-867: LGTM — void in synchronous methods correctly signals intentional fire-and-forget.

_jobProcessing and processJobs are synchronous; the void prefix satisfies the @typescript-eslint/no-floating-promises rule while preserving the intended behavior.

Also applies to: 922-922, 929-929

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@KevLehman KevLehman marked this pull request as draft February 10, 2026 18:25
@KevLehman KevLehman force-pushed the chore/eslint-promises branch from 6750bb5 to 8b62d88 Compare February 10, 2026 19:01
@KevLehman KevLehman marked this pull request as ready for review February 10, 2026 20:21
Copy link
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 75 files

Copy link
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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ee/apps/authorization-service/src/service.ts (1)

10-44: ⚠️ Potential issue | 🟠 Major

No unhandled-rejection safety net for the bootstrap IIFE.

Same concern as omnichannel-transcript/src/service.ts: this file has no process.on('unhandledRejection', ...) handler. If getConnection(), api.start(), or any other awaited call rejects, the error is silently lost. Consider adding a .catch() on the IIFE or a global rejection handler, as ddp-streamer/src/service.ts does.

Suggested fix
-void (async () => {
+void (async () => {
   // ...
-})();
+})().catch((err) => {
+  console.error('Failed to start authorization-service', err);
+  process.exit(1);
+});
🤖 Fix all issues with AI agents
In `@ee/apps/ddp-streamer/src/DDPStreamer.ts`:
- Line 261: The call to InstanceStatus.registerInstance('ddp-streamer', {}) is
prefixed with void which prevents its rejection from being caught by the
surrounding try/catch; change this to await
InstanceStatus.registerInstance('ddp-streamer', {}) so registration failures
propagate into the existing error handler (or, if the enclosing function is not
async, make it async or explicitly handle the promise rejection and rethrow).
Ensure the enclosing startup function (the one containing the try/catch around
the register call) is async or otherwise awaits the promise so service
registration failures are surfaced and handled.

In `@ee/packages/media-calls/src/sip/providers/OutgoingSipCall.ts`:
- Line 242: The fire-and-forget call to
callerAgent.onRemoteDescriptionChanged(this.call._id, negotiationId) risks
unhandled rejections and skips the existing catch cleanup (sending SIP error and
removing the negotiation from this.inboundRenegotiations); change the call to
either await callerAgent.onRemoteDescriptionChanged(...) inside the surrounding
try so rejections hit the catch, or if keeping non-blocking, append a .catch(err
=> { send the same SIP error response (res) and remove
this.inboundRenegotiations.get(negotiationId) / delete the entry from
this.inboundRenegotiations }) so any failure performs the same cleanup as the
current catch block rather than leaving a stale entry.

In `@packages/livechat/src/lib/hooks.ts`:
- Line 94: The call to createOrUpdateGuest from updateIframeGuestData currently
discards promise rejections (void createOrUpdateGuest(guestData)); attach a
.catch handler to that returned promise to log failures so network errors from
Livechat.grantVisitor are visible; locate the call site in updateIframeGuestData
and change it to call createOrUpdateGuest(guestData).catch(err =>
console.error('createOrUpdateGuest failed', err)) (or use the existing
widget/logger if available) to surface errors.
🧹 Nitpick comments (2)
packages/livechat/src/entry.ts (1)

18-18: Consider adding a .catch() to surface initialization failures.

With void init(), if the dynamic import or render fails, the rejection is silently swallowed and the user sees a blank page with no feedback. A minimal error handler would improve debuggability:

Suggested change
-void init();
+void init().catch((err) => console.error('Failed to initialize app:', err));
packages/livechat/src/lib/connection.ts (1)

54-64: clearAlerts and displayAlert no longer need to be async.

With the await removed from the store.setState calls, these methods contain no asynchronous operations. The async keyword is now misleading — it wraps the return in an unnecessary Promise. Note that callers in handleConnected and handleDisconnected still await these methods, so removing async (and updating return types) would be a clean follow-up.

Suggested change
-	async clearAlerts() {
+	clearAlerts() {
 		const { alerts } = store.state;
 		store.setState({
 			alerts: alerts?.filter((alert) => ![livechatDisconnectedAlertId, livechatConnectedAlertId].includes(alert.id)),
 		});
 	},

-	async displayAlert(alert = {}) {
+	displayAlert(alert = {}) {
 		const { alerts } = store.state;
 		store.setState({ alerts: (alerts?.push(alert), alerts) });
 	},
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8228125 and c8793c8.

📒 Files selected for processing (54)
  • apps/meteor/.eslintrc.json
  • apps/meteor/.scripts/run-ha.ts
  • ee/apps/account-service/src/service.ts
  • ee/apps/authorization-service/src/service.ts
  • ee/apps/ddp-streamer/src/Client.ts
  • ee/apps/ddp-streamer/src/DDPStreamer.ts
  • ee/apps/ddp-streamer/src/service.ts
  • ee/apps/omnichannel-transcript/src/service.ts
  • ee/apps/presence-service/src/service.ts
  • ee/apps/queue-worker/src/service.ts
  • ee/packages/federation-matrix/src/events/index.ts
  • ee/packages/federation-matrix/tsconfig.build.json
  • ee/packages/federation-matrix/tsconfig.json
  • ee/packages/media-calls/src/internal/agents/CallSignalProcessor.ts
  • ee/packages/media-calls/src/sip/Session.ts
  • ee/packages/media-calls/src/sip/providers/IncomingSipCall.ts
  • ee/packages/media-calls/src/sip/providers/OutgoingSipCall.ts
  • ee/packages/omnichannel-services/src/OmnichannelTranscript.ts
  • ee/packages/presence/src/Presence.ts
  • ee/packages/ui-theming/src/hooks/useThemeMode.ts
  • packages/agenda/src/Agenda.ts
  • packages/core-services/src/LocalBroker.ts
  • packages/ddp-client/__examples__/simple.ts
  • packages/ddp-client/package.json
  • packages/ddp-client/src/ClientStream.ts
  • packages/ddp-client/src/Connection.ts
  • packages/ddp-client/src/DDPSDK.ts
  • packages/ddp-client/tsconfig.build.json
  • packages/ddp-client/tsconfig.json
  • packages/eslint-config/standard/index.js
  • packages/fuselage-ui-kit/.eslintrc.json
  • packages/fuselage-ui-kit/src/blocks/VideoConferenceBlock/VideoConferenceBlock.tsx
  • packages/fuselage-ui-kit/src/elements/ButtonElement.tsx
  • packages/fuselage-ui-kit/src/elements/ChannelsSelectElement/ChannelsSelectElement.tsx
  • packages/fuselage-ui-kit/src/elements/ChannelsSelectElement/MultiChannelsSelectElement.tsx
  • packages/fuselage-ui-kit/src/elements/IconButtonElement.tsx
  • packages/fuselage-ui-kit/src/elements/MultiStaticSelectElement.tsx
  • packages/fuselage-ui-kit/src/elements/OverflowElement.tsx
  • packages/fuselage-ui-kit/src/elements/StaticSelectElement.tsx
  • packages/fuselage-ui-kit/src/elements/TabElement.tsx
  • packages/fuselage-ui-kit/src/elements/UsersSelectElement/MultiUsersSelectElement.tsx
  • packages/fuselage-ui-kit/src/elements/UsersSelectElement/UsersSelectElement.tsx
  • packages/i18n/tsconfig.json
  • packages/instance-status/src/index.ts
  • packages/livechat/.eslintrc.json
  • packages/livechat/src/components/App/App.tsx
  • packages/livechat/src/entry.ts
  • packages/livechat/src/hooks/livechatRoomSubscriptionHooks.ts
  • packages/livechat/src/hooks/useRoomMessagesSubscription.ts
  • packages/livechat/src/lib/connection.ts
  • packages/livechat/src/lib/hooks.ts
  • packages/livechat/src/lib/transcript.ts
  • packages/media-signaling/src/lib/Call.ts
  • packages/mock-providers/src/MockedAppRootBuilder.tsx
✅ Files skipped from review due to trivial changes (1)
  • packages/livechat/src/components/App/App.tsx
🚧 Files skipped from review as they are similar to previous changes (14)
  • packages/core-services/src/LocalBroker.ts
  • packages/ddp-client/src/ClientStream.ts
  • ee/apps/ddp-streamer/src/Client.ts
  • packages/media-signaling/src/lib/Call.ts
  • packages/instance-status/src/index.ts
  • apps/meteor/.eslintrc.json
  • ee/apps/account-service/src/service.ts
  • ee/packages/media-calls/src/sip/providers/IncomingSipCall.ts
  • apps/meteor/.scripts/run-ha.ts
  • packages/eslint-config/standard/index.js
  • ee/packages/media-calls/src/sip/Session.ts
  • ee/packages/media-calls/src/internal/agents/CallSignalProcessor.ts
  • packages/ddp-client/src/Connection.ts
  • packages/agenda/src/Agenda.ts
🧰 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/livechat/src/lib/transcript.ts
  • packages/fuselage-ui-kit/src/elements/UsersSelectElement/UsersSelectElement.tsx
  • packages/fuselage-ui-kit/src/blocks/VideoConferenceBlock/VideoConferenceBlock.tsx
  • packages/ddp-client/src/DDPSDK.ts
  • packages/fuselage-ui-kit/src/elements/ChannelsSelectElement/MultiChannelsSelectElement.tsx
  • ee/apps/queue-worker/src/service.ts
  • packages/fuselage-ui-kit/src/elements/ButtonElement.tsx
  • packages/livechat/src/hooks/livechatRoomSubscriptionHooks.ts
  • ee/apps/authorization-service/src/service.ts
  • packages/livechat/src/hooks/useRoomMessagesSubscription.ts
  • ee/apps/ddp-streamer/src/service.ts
  • ee/packages/presence/src/Presence.ts
  • ee/apps/ddp-streamer/src/DDPStreamer.ts
  • ee/packages/media-calls/src/sip/providers/OutgoingSipCall.ts
  • packages/fuselage-ui-kit/src/elements/UsersSelectElement/MultiUsersSelectElement.tsx
  • packages/fuselage-ui-kit/src/elements/MultiStaticSelectElement.tsx
  • packages/fuselage-ui-kit/src/elements/StaticSelectElement.tsx
  • packages/fuselage-ui-kit/src/elements/TabElement.tsx
  • ee/packages/federation-matrix/src/events/index.ts
  • packages/ddp-client/__examples__/simple.ts
  • packages/fuselage-ui-kit/src/elements/OverflowElement.tsx
  • packages/mock-providers/src/MockedAppRootBuilder.tsx
  • packages/fuselage-ui-kit/src/elements/IconButtonElement.tsx
  • packages/livechat/src/lib/connection.ts
  • ee/apps/omnichannel-transcript/src/service.ts
  • packages/livechat/src/entry.ts
  • ee/packages/omnichannel-services/src/OmnichannelTranscript.ts
  • packages/fuselage-ui-kit/src/elements/ChannelsSelectElement/ChannelsSelectElement.tsx
  • packages/livechat/src/lib/hooks.ts
  • ee/packages/ui-theming/src/hooks/useThemeMode.ts
  • ee/apps/presence-service/src/service.ts
🧠 Learnings (16)
📚 Learning: 2025-12-18T15:18:31.688Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37773
File: apps/meteor/client/views/mediaCallHistory/MediaCallHistoryInternal.tsx:24-34
Timestamp: 2025-12-18T15:18:31.688Z
Learning: In apps/meteor/client/views/mediaCallHistory/MediaCallHistoryInternal.tsx, for internal call history items, the item.contactId is guaranteed to always match either the caller.id or callee.id in the call data, so the contact resolution in getContact will never result in undefined.

Applied to files:

  • packages/fuselage-ui-kit/src/blocks/VideoConferenceBlock/VideoConferenceBlock.tsx
📚 Learning: 2026-01-27T20:57:56.529Z
Learnt from: nazabucciarelli
Repo: RocketChat/Rocket.Chat PR: 38294
File: apps/meteor/server/hooks/sauMonitorHooks.ts:0-0
Timestamp: 2026-01-27T20:57:56.529Z
Learning: In Rocket.Chat, the `accounts.login` event listened to by DeviceManagementService is only broadcast when running in microservices mode (via DDPStreamer), not in monolith mode. The `Accounts.onLogin` hook in sauMonitorHooks.ts runs in monolith deployments. These are mutually exclusive deployment modes, so there's no duplication of event emissions between these two code paths.

Applied to files:

  • packages/ddp-client/src/DDPSDK.ts
  • ee/apps/ddp-streamer/src/DDPStreamer.ts
📚 Learning: 2025-11-17T15:07:13.273Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37398
File: packages/fuselage-ui-kit/src/surfaces/FuselageSurfaceRenderer.tsx:357-363
Timestamp: 2025-11-17T15:07:13.273Z
Learning: In packages/fuselage-ui-kit/src/surfaces/FuselageSurfaceRenderer.tsx, IconElement is a presentational, non-actionable element that does not require wrapping in AppIdProvider, similar to plain_text and mrkdwn renderers. Only actionable elements (those with actions, actionId, or interactive behavior) should be wrapped in AppIdProvider.

Applied to files:

  • packages/fuselage-ui-kit/src/elements/ButtonElement.tsx
  • packages/fuselage-ui-kit/src/elements/StaticSelectElement.tsx
  • packages/fuselage-ui-kit/src/elements/TabElement.tsx
  • packages/fuselage-ui-kit/src/elements/IconButtonElement.tsx
📚 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: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings by mapping subscription documents to room IDs, never undefined, even when user has no room subscriptions.

Applied to files:

  • packages/livechat/src/hooks/useRoomMessagesSubscription.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: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings (mapping subscription documents to room IDs), never undefined, even when user has no room subscriptions.

Applied to files:

  • packages/livechat/src/hooks/useRoomMessagesSubscription.ts
📚 Learning: 2025-11-05T21:04:35.787Z
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 37357
File: ee/packages/federation-matrix/src/setup.ts:103-120
Timestamp: 2025-11-05T21:04:35.787Z
Learning: In Rocket.Chat's federation-matrix setup (ee/packages/federation-matrix/src/setup.ts and apps/meteor/ee/server/startup/federation.ts), configureFederationMatrixSettings does not need to be called before setupFederationMatrix. The SDK's init() establishes infrastructure (database, event handlers, APIs) first, and the configuration can be applied later via settings watchers before actual federation events are processed. The config only matters when events actually occur, at which point all infrastructure is already configured.

Applied to files:

  • ee/apps/ddp-streamer/src/service.ts
  • ee/packages/federation-matrix/src/events/index.ts
📚 Learning: 2025-12-10T21:00:54.909Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37091
File: ee/packages/abac/jest.config.ts:4-7
Timestamp: 2025-12-10T21:00:54.909Z
Learning: Rocket.Chat monorepo: Jest testMatch pattern '<rootDir>/src/**/*.spec.(ts|js|mjs)' is valid in this repo and used across multiple packages (e.g., packages/tools, ee/packages/omnichannel-services). Do not flag it as invalid in future reviews.

Applied to files:

  • packages/ddp-client/tsconfig.build.json
  • packages/fuselage-ui-kit/.eslintrc.json
  • ee/packages/federation-matrix/tsconfig.json
  • packages/ddp-client/tsconfig.json
  • packages/i18n/tsconfig.json
  • ee/packages/federation-matrix/tsconfig.build.json
  • packages/livechat/.eslintrc.json
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to **/*.spec.ts : Use `.spec.ts` extension for test files (e.g., `login.spec.ts`)

Applied to files:

  • packages/fuselage-ui-kit/.eslintrc.json
  • ee/packages/federation-matrix/tsconfig.json
  • packages/ddp-client/tsconfig.json
  • ee/packages/federation-matrix/tsconfig.build.json
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to **/*.{ts,tsx,js} : Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests

Applied to files:

  • packages/fuselage-ui-kit/.eslintrc.json
  • ee/packages/federation-matrix/tsconfig.json
  • packages/ddp-client/package.json
  • packages/ddp-client/tsconfig.json
  • packages/i18n/tsconfig.json
  • ee/packages/federation-matrix/tsconfig.build.json
  • packages/livechat/.eslintrc.json
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to **/*.{ts,tsx,js} : Avoid code comments in the implementation

Applied to files:

  • packages/fuselage-ui-kit/.eslintrc.json
  • packages/livechat/.eslintrc.json
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : All test files must be created in `apps/meteor/tests/e2e/` directory

Applied to files:

  • packages/fuselage-ui-kit/.eslintrc.json
  • packages/ddp-client/tsconfig.json
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Group related tests in the same file

Applied to files:

  • packages/fuselage-ui-kit/.eslintrc.json
📚 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:

  • ee/apps/ddp-streamer/src/DDPStreamer.ts
📚 Learning: 2025-12-09T20:01:00.324Z
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 37532
File: ee/packages/federation-matrix/src/FederationMatrix.ts:920-927
Timestamp: 2025-12-09T20:01:00.324Z
Learning: When reviewing federation invite handling in Rocket.Chat (specifically under ee/packages/federation-matrix), understand that rejecting an invite via federationSDK.rejectInvite() triggers an event-driven cleanup: a leave event is emitted and handled by handleLeave() in ee/packages/federation-matrix/src/events/member.ts, which calls Room.performUserRemoval() to remove the subscription. Do not add explicit cleanup in the reject branch of handleInvite(); rely on the existing leave-event flow for cleanup. If making changes, ensure this invariant remains and that any related paths still funnel cleanup through the leave event to avoid duplicate or missing removals.

Applied to files:

  • ee/packages/federation-matrix/src/events/index.ts
📚 Learning: 2025-10-06T20:30:45.540Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37152
File: packages/apps-engine/tests/test-data/storage/storage.ts:101-122
Timestamp: 2025-10-06T20:30:45.540Z
Learning: In `packages/apps-engine/tests/test-data/storage/storage.ts`, the stub methods (updatePartialAndReturnDocument, updateStatus, updateSetting, updateAppInfo, updateMarketplaceInfo) intentionally throw "Method not implemented." Tests using these methods must stub them using `SpyOn` from the test library rather than relying on actual implementations.

Applied to files:

  • packages/mock-providers/src/MockedAppRootBuilder.tsx
📚 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:

  • ee/apps/omnichannel-transcript/src/service.ts
  • packages/livechat/.eslintrc.json
🧬 Code graph analysis (6)
ee/apps/ddp-streamer/src/DDPStreamer.ts (1)
packages/instance-status/src/index.ts (1)
  • InstanceStatus (104-110)
packages/fuselage-ui-kit/src/elements/TabElement.tsx (1)
apps/meteor/app/integrations/server/lib/ScriptEngine.ts (1)
  • disabled (167-169)
ee/packages/federation-matrix/src/events/index.ts (5)
ee/packages/federation-matrix/src/events/ping.ts (1)
  • ping (3-7)
ee/packages/federation-matrix/src/events/message.ts (1)
  • message (113-416)
ee/packages/federation-matrix/src/events/reaction.ts (1)
  • reaction (9-92)
ee/packages/federation-matrix/src/events/member.ts (1)
  • member (257-280)
ee/packages/federation-matrix/src/events/edu.ts (1)
  • edus (9-74)
packages/mock-providers/src/MockedAppRootBuilder.tsx (1)
apps/meteor/app/lib/server/functions/notifications/email.js (1)
  • lng (25-25)
packages/livechat/src/lib/connection.ts (1)
packages/livechat/src/lib/room.js (1)
  • alert (89-89)
packages/livechat/src/lib/hooks.ts (1)
packages/core-services/src/index.ts (1)
  • api (55-55)
⏰ 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). (13)
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: 🔨 Test UI (EE) / MongoDB 8.2 coverage (2/5)
  • GitHub Check: 🔨 Test UI (EE) / MongoDB 8.2 coverage (1/5)
  • GitHub Check: 🔨 Test UI (EE) / MongoDB 8.2 coverage (4/5)
  • GitHub Check: 🔨 Test UI (EE) / MongoDB 8.2 coverage (3/5)
  • GitHub Check: 🔨 Test UI (EE) / MongoDB 8.2 coverage (5/5)
  • GitHub Check: 🔨 Test UI (CE) / MongoDB 8.2 (2/4)
  • GitHub Check: 🔨 Test UI (CE) / MongoDB 8.2 (3/4)
  • GitHub Check: 🔨 Test UI (CE) / MongoDB 8.2 (1/4)
  • GitHub Check: 🔨 Test UI (CE) / MongoDB 8.2 (4/4)
  • GitHub Check: 🔨 Test API (CE) / MongoDB 8.2 (1/1)
  • GitHub Check: 🔨 Test API (EE) / MongoDB 8.2 coverage (1/1)
  • GitHub Check: 🔨 Test Federation Matrix
🔇 Additional comments (36)
packages/ddp-client/__examples__/simple.ts (1)

37-39: LGTM!

The void prefix correctly marks the async IIFE as intentionally fire-and-forget, satisfying the @typescript-eslint/no-floating-promises rule without altering behavior.

packages/livechat/src/hooks/useRoomMessagesSubscription.ts (1)

14-16: LGTM — void prefix correctly marks the fire-and-forget promise.

The void operator makes the intentional discard of the onMessage promise explicit for the linter without changing runtime behavior.

packages/fuselage-ui-kit/src/elements/OverflowElement.tsx (1)

25-25: LGTM — void prefixes correctly suppress floating promises in fire-and-forget UI handlers.

Both changes follow the established PR-wide pattern for satisfying @typescript-eslint/no-floating-promises without altering control flow. The fire-and-forget semantics are appropriate for these UI event callbacks.

Also applies to: 41-41

packages/fuselage-ui-kit/src/blocks/VideoConferenceBlock/VideoConferenceBlock.tsx (1)

51-88: LGTM — void prefix correctly suppresses floating-promise lint errors.

The three handlers (joinHandler, callAgainHandler, openCallInfo) now use void action(...) to explicitly mark the returned promise as intentionally unhandled, which is the idiomatic pattern for satisfying @typescript-eslint/no-floating-promises in fire-and-forget event handlers.

ee/packages/ui-theming/src/hooks/useThemeMode.ts (1)

17-22: LGTM — type refinement and new high-contrast entry look correct.

The internal type now accurately reflects the saveUserPreferences return type, while the external hook signature on line 11 intentionally narrows to () => void for fire-and-forget semantics. The new 'high-contrast' entry is consistent with the existing pattern.

packages/ddp-client/package.json (1)

10-11: LGTM!

Clean separation: build and dev now target the dedicated tsconfig.build.json (which excludes tests and sets output dirs), while typecheck continues to use the broader tsconfig.json. This is a well-structured split.

packages/ddp-client/tsconfig.json (1)

1-10: LGTM!

Good refactoring — rootDir/outDir moved to the build config where they belong, and include expanded to cover __examples__ and __mocks__ for broader type-checking coverage.

Nit: sourceMap: true on line 7 is effectively unused since this config is only consumed by tsc --noEmit, but it's harmless.

packages/ddp-client/tsconfig.build.json (1)

1-13: LGTM!

Clean dedicated build config. Correctly scopes include to ./src/**/* and excludes test files from the compiled output.

packages/livechat/.eslintrc.json (1)

99-100: LGTM — consistent with the PR-wide pattern of disabling no-misused-promises in UI packages.

packages/fuselage-ui-kit/src/elements/ButtonElement.tsx (1)

14-16: LGTM — correct use of void to suppress the floating promise in a synchronous event handler.

packages/fuselage-ui-kit/src/elements/UsersSelectElement/UsersSelectElement.tsx (1)

26-31: LGTM — consistent void prefix for fire-and-forget action dispatch.

packages/fuselage-ui-kit/src/elements/StaticSelectElement.tsx (1)

21-26: LGTM — standard void prefix for the action call.

packages/fuselage-ui-kit/src/elements/UsersSelectElement/MultiUsersSelectElement.tsx (1)

22-27: LGTM — consistent with the single-select counterpart, correctly guarding for array values.

packages/fuselage-ui-kit/.eslintrc.json (1)

3-11: LGTM — correctly disables no-misused-promises for TypeScript files in this UI kit package.

Minor note: this file uses **/*.ts glob patterns while packages/livechat/.eslintrc.json uses *.ts. Both work in ESLint overrides, but you may want to standardize the glob style across packages for consistency.

packages/fuselage-ui-kit/src/elements/ChannelsSelectElement/ChannelsSelectElement.tsx (1)

21-26: LGTM — consistent void prefix matching the pattern across all select elements.

packages/fuselage-ui-kit/src/elements/ChannelsSelectElement/MultiChannelsSelectElement.tsx (1)

23-23: LGTM!

The void prefix correctly marks the fire-and-forget intent for the promise-returning action call.

packages/fuselage-ui-kit/src/elements/IconButtonElement.tsx (1)

16-18: LGTM!

Consistent void-prefixed fire-and-forget pattern for the click handler.

packages/fuselage-ui-kit/src/elements/MultiStaticSelectElement.tsx (1)

22-27: LGTM!

Consistent void-prefixed fire-and-forget pattern for the change handler.

packages/fuselage-ui-kit/src/elements/TabElement.tsx (1)

25-28: LGTM!

The void prefix correctly discards the promise from action(e). Operator precedence is fine here — void binds tighter than &&, so action(e) is called and its result discarded only when !disabled.

packages/mock-providers/src/MockedAppRootBuilder.tsx (3)

121-129: Synchronous throws are consistent with these methods' void return types.

The change from Promise.reject(...) to synchronous throw aligns these stubs with their non-async signatures, while uploadToEndpoint and callMethod (lines 119–120) correctly retain Promise.reject since they return Promise<…>. Clean separation.


652-657: void prefix correctly satisfies no-floating-promises.

Both the already-initialized and the on('initialized', ...) callback paths properly mark the changeLanguage return value as intentionally discarded.


730-730: void i18n.init() is appropriate here.

Given initImmediate: false (line 628), init completes synchronously, but the method still returns a Promise at the type level. The void operator correctly signals the linter that the promise is intentionally unhandled.

packages/livechat/src/lib/transcript.ts (1)

62-62: LGTM — void prefix correctly marks the alert as fire-and-forget.

The transcriptSentAlert is a non-critical UI notification with a timeout, so ignoring its promise is reasonable here.

packages/livechat/src/lib/connection.ts (1)

31-31: LGTM — void is appropriate here since alert clearing after connect is non-critical.

packages/i18n/tsconfig.json (2)

17-17: Good addition of jest.config.ts to include.

Ensures the Jest configuration file is type-checked alongside the source.


4-15: target: "es2024" with lib: ["ES2023"] creates a technical mismatch, but has no practical impact.

The config specifies target: "es2024" while lib only provides ES2023 type definitions. This is technically inconsistent — the compiler assumes an ES2024 runtime, but type definitions don't include ES2024-only APIs like Object.groupBy, Promise.withResolvers, or ArrayBuffer.resize.

However, the code in this package doesn't use any ES2024-only APIs, so the mismatch has no real impact. If this inconsistency bothers you, either align target and lib (both ES2023) or expand lib to match the target, but it's not blocking any actual issues.

packages/livechat/src/hooks/livechatRoomSubscriptionHooks.ts (2)

15-15: LGTM — void prefix correctly marks fire-and-forget promises.

Both additions properly silence @typescript-eslint/no-floating-promises for these intentionally unhandled async calls.

Also applies to: 45-45


28-31: No change needed — onAgentStatusChange is correctly called without void prefix.

onAgentStatusChange is a synchronous function and does not return a Promise, unlike onAgentChange (async) and onQueuePositionChange (async). The void prefix is only needed for functions that return Promises to satisfy ESLint's floating promises rule. The code is correct as-is.

ee/apps/ddp-streamer/src/service.ts (1)

9-9: LGTM!

The void prefix correctly satisfies the no-floating-promises ESLint rule, and this file already has process.on('unhandledRejection', ...) and process.on('uncaughtException', ...) handlers (Lines 45–70) to catch bootstrap failures.

packages/ddp-client/src/DDPSDK.ts (1)

115-122: LGTM!

The void prefix correctly marks the fire-and-forget loginWithToken call in the reconnection handler. This is an event callback where the promise result cannot be propagated, and the void makes the intent explicit for the linter.

ee/packages/federation-matrix/tsconfig.json (1)

8-8: LGTM!

Broadening from a single entry file to "include": ["./src/**/*"] ensures all source files are type-checked, which is necessary for the TypeScript-aware ESLint rules to function across the package.

ee/packages/federation-matrix/src/events/index.ts (1)

8-15: LGTM!

void is correctly applied only to the two async functions (ping, edus) while the synchronous event registration functions (message, reaction, member, room) are left as-is. This is consistent with the ESLint no-floating-promises rule requirements.

ee/packages/federation-matrix/tsconfig.build.json (1)

8-9: LGTM!

The broader include pattern aligns with the base tsconfig.json change, and test files are properly excluded from the build output.

ee/packages/presence/src/Presence.ts (1)

301-304: void on broadcast is acceptable here.

The presence status broadcast is non-critical and self-heals on the next status change. This is a reasonable fire-and-forget pattern.

packages/livechat/src/lib/hooks.ts (1)

138-138: Remaining void-wrapped calls are appropriate fire-and-forget patterns.

  • sendVisitorNavigation (Line 138): analytics-style page tracking, best-effort.
  • i18next.changeLanguage (Line 290): language switch is non-critical.
  • api[fn](...args) (Line 351): postMessage dispatch has no response channel, so fire-and-forget is the only option.

Also applies to: 289-290, 351-351

ee/apps/ddp-streamer/src/DDPStreamer.ts (1)

69-69: Broadcast and connection-count void calls are appropriate fire-and-forget.

These are non-critical event notifications and periodic metric updates that self-heal. The void prefix correctly satisfies the lint rule here.

Also applies to: 185-185, 191-191, 204-204, 215-215

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@KevLehman KevLehman added the stat: QA assured Means it has been tested and approved by a company insider label Feb 10, 2026
@dionisio-bot dionisio-bot bot added the stat: ready to merge PR tested and approved waiting for merge label Feb 10, 2026
@kodiakhq kodiakhq bot merged commit 1beb9c6 into develop Feb 11, 2026
44 checks passed
@kodiakhq kodiakhq bot deleted the chore/eslint-promises branch February 11, 2026 18:41
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants