Skip to content

Conversation

@sanki92
Copy link

@sanki92 sanki92 commented Dec 14, 2025

Proposed changes

Fixes Slack import where messages dont show in chat history even though they're in the database.

The problem is in MessageConverter.buildMessageObject - it was setting fields to null instead of undefined. When tmid (thread message ID) is null, the message loading query breaks and nothing shows up in chat.

Changed to use ?? operator to convert nullundefined while keeping valid falsy values like 0 and false:

  • Fields like tmid, tlm, tcount, groupable, editedAt, etc. now use ?? undefined
  • Arrays mentions and channels default to [] instead of null

This makes imported messages match the structure of regular messages

Issue(s)

Closes #37058

Steps to test or reproduce

  1. Do a Slack import (any size works, even small ones)
  2. Open an imported channel or DM
  3. Messages should now show up (instead of "Start of conversation")
  4. Check that search still works and no errors when hovering search results

Before this fix, you'd see empty chat history even though messages are in the database and searchable.

Further comments

Thanks to @tlueder for the detailed bug report and database investigation that made this fix possible.

For existing imports with the bug, you can clean up the database using the script from issue #37058:

db.rocketchat_message.updateMany({ "tmid": null }, { $unset: { "tmid": "" } });
db.rocketchat_message.updateMany({ "mentions": null }, { $set: { "mentions": [] } });
// etc.

Summary by CodeRabbit

  • Bug Fixes
    • Improved message import handling of missing optional fields: mentions and channels now default to empty lists, replies, edit info, and reactions are preserved when present, and optional fields are included only when available to prevent null/undefined values and make imports more stable and consistent.

✏️ Tip: You can customize this high-level summary in your review settings.

@changeset-bot
Copy link

changeset-bot bot commented Dec 14, 2025

⚠️ No Changeset found

Latest commit: 240192f

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

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Dec 14, 2025

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@CLAassistant
Copy link

CLAassistant commented Dec 14, 2025

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 14, 2025

Walkthrough

Updated MessageConverter.buildMessageObject to use conditional spreads and nullish coalescing so optional fields (mentions, channels, replies, editedBy, reactions, attachments, etc.) are only included when present or default to empty arrays, preventing undefined/null assignments.

Changes

Cohort / File(s) Summary
Message Conversion Defaults
apps/meteor/app/importer/server/classes/converters/MessageConverter.ts
Reworked buildMessageObject to: use ?? [] for mentions and channels; compute replies, editedBy, and reactions locally when present; and apply conditional object spreads so fields like t, groupable, tmid, tlm, tcount, replies, editedAt, editedBy, _importFile, url, attachments, bot, emoji, alias, _id, and reactions are only included when non-null/non-empty.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 I hopped through code, a careful little shove,

turned undefined to lists and gave each field some love.
Now mentions march and channels stand in line,
replies and reactions show up just fine.
Hooray — no more nulls where messages should shine!

🚥 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 title accurately describes the main fix: preventing null fields from Slack imports that break message history display.
Linked Issues check ✅ Passed The PR addresses the core issue #37058 by converting null values to undefined and using conditional spreads to avoid storing null fields that break message-loading queries.
Out of Scope Changes check ✅ Passed All changes are confined to MessageConverter.buildMessageObject and directly address the null-field problem in Slack imports; no unrelated modifications detected.
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.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 8c5df77 and 240192f.

📒 Files selected for processing (1)
  • apps/meteor/app/importer/server/classes/converters/MessageConverter.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/meteor/app/importer/server/classes/converters/MessageConverter.ts

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.

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: 0

🧹 Nitpick comments (1)
apps/meteor/app/importer/server/classes/converters/MessageConverter.ts (1)

86-87: Consider ternary operator for clearer null-handling.

The && operator with ?? can preserve non-null/undefined falsy values (false, 0, ''). If data.mentions is false or 0, the expression evaluates to that value instead of [].

While Slack import data is unlikely to contain such values, using a ternary would be more explicit:

-const mentions = (data.mentions && (await this.convertMessageMentions(data))) ?? [];
-const channels = (data.channels && (await this.convertMessageChannels(data))) ?? [];
+const mentions = data.mentions ? (await this.convertMessageMentions(data)) ?? [] : [];
+const channels = data.channels ? (await this.convertMessageChannels(data)) ?? [] : [];
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 8bf0bab and 8c5df77.

📒 Files selected for processing (1)
  • apps/meteor/app/importer/server/classes/converters/MessageConverter.ts (2 hunks)
🧰 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/importer/server/classes/converters/MessageConverter.ts
🔇 Additional comments (4)
apps/meteor/app/importer/server/classes/converters/MessageConverter.ts (4)

97-101: Excellent fix for the null-field issue.

Using ?? instead of || correctly preserves meaningful falsy values while converting null to undefined:

  • Line 98: groupable can be explicitly false (message is not groupable)
  • Line 99: tmid is the critical fix—null breaks message-loading queries; now properly undefined
  • Line 101: tcount can be 0 (thread with no replies yet)

This directly resolves the root cause described in issue #37058.


102-102: Correct handling of optional replies field.

The logic properly omits the replies property when data.replies is absent (undefined prevents property insertion), while preserving the converted array when present. This aligns with the conditional property pattern used elsewhere (lines 113-114).


103-104: Proper null-to-undefined conversion for edit metadata.

Both fields correctly convert null to undefined:

  • editedAt: preserves valid timestamps (including 0 if present) while removing null
  • editedBy: chains user lookup with ?? to handle missing user data gracefully

107-108: Consistent null-handling for remaining optional fields.

All fields correctly use ?? to convert null → undefined while preserving meaningful falsy values:

  • bot (line 110): preserves explicit false (not a bot) vs undefined (unknown)
  • url, alias: preserve empty strings if present (more explicit than undefined)
  • _importFile: import metadata properly defaulted

Also applies to: 110-110, 112-112

Abhijeet212004 added a commit to Abhijeet212004/Rocket.Chat that referenced this pull request Jan 7, 2026
- Adds migration v333 to fix issue where Slack imports create messages with null fields
- Removes null values from fields like tmid, groupable, tlm, etc. using
- Converts null mentions and urls arrays to empty arrays using
- Fixes message history not loading after Slack import

Fixes RocketChat#37058
Complements RocketChat#37805
@ghuls
Copy link

ghuls commented Jan 12, 2026

@sanki92 With this pull request it still seems like Slack messages do no show up after import.

To show any message at all, the following is required (other commands are also needed to properly display the messages):

db.rocketchat_message.updateMany(
{ "tmid": null },
{ $unset: { "tmid": "" } }
);

@ghuls
Copy link

ghuls commented Jan 13, 2026

@sanki92 I am not really familiar with MongoDB, but according to Claud AI:

The issue is that ?? undefined still adds the field with an undefined value, which MongoDB stores as null. To prevent fields from being added when they're null/undefined, you need to conditionally include them.

Key changes:

?? undefined → ...(condition && { field: value })
Use != null to check for both null and undefined (double equals intentional)
Use && for truthy checks when appropriate
Fields are only added to the object if the condition is true

The following seems to work and imported Slack message finally show up after import:

diff --git a/apps/meteor/app/importer/server/classes/converters/MessageConverter.ts b/apps/meteor/app/importer/server/classes/converters/MessageConverter.ts
index 87ddfe29c4..3aed0db174 100644
--- a/apps/meteor/app/importer/server/classes/converters/MessageConverter.ts
+++ b/apps/meteor/app/importer/server/classes/converters/MessageConverter.ts
@@ -94,24 +94,24 @@ export class MessageConverter extends RecordConverter<IImportMessageRecord> {
                        },
                        msg: data.msg,
                        ts: data.ts,
-                       t: data.t ?? undefined,
-                       groupable: data.groupable ?? undefined,
-                       tmid: data.tmid ?? undefined,
-                       tlm: data.tlm ?? undefined,
-                       tcount: data.tcount ?? undefined,
-                       replies: (data.replies && (await this.convertMessageReplies(data.replies))) ?? undefined,
-                       editedAt: data.editedAt ?? undefined,
-                       editedBy: data.editedBy && ((await this._cache.findImportedUser(data.editedBy)) ?? undefined),
                        mentions,
                        channels,
-                       _importFile: data._importFile ?? undefined,
-                       url: data.url ?? undefined,
-                       attachments: data.attachments,
-                       bot: data.bot ?? undefined,
-                       emoji: data.emoji,
-                       alias: data.alias ?? undefined,
-                       ...(data._id ? { _id: data._id } : {}),
-                       ...(data.reactions ? { reactions: await this.convertMessageReactions(data.reactions) } : {}),
+                       ...(data.t != null && { t: data.t }),
+                       ...(data.groupable != null && { groupable: data.groupable }),
+                       ...(data.tmid != null && { tmid: data.tmid }),
+                       ...(data.tlm != null && { tlm: data.tlm }),
+                       ...(data.tcount != null && { tcount: data.tcount }),
+                       ...(data.replies && { replies: await this.convertMessageReplies(data.replies) }),
+                       ...(data.editedAt && { editedAt: data.editedAt }),
+                       ...(data.editedBy && { editedBy: await this._cache.findImportedUser(data.editedBy) }),
+                       ...(data._importFile && { _importFile: data._importFile }),
+                       ...(data.url && { url: data.url }),
+                       ...(data.attachments && { attachments: data.attachments }),
+                       ...(data.bot != null && { bot: data.bot }),
+                       ...(data.emoji && { emoji: data.emoji }),
+                       ...(data.alias && { alias: data.alias }),
+                       ...(data._id && { _id: data._id }),
+                       ...(data.reactions && { reactions: await this.convertMessageReactions(data.reactions) }),
                };
        }

Can you confirm if this change would make sense or if it need additional adaptations?

@sanki92 sanki92 force-pushed the fix/slack-import-null-fields branch from 8c5df77 to 240192f Compare January 13, 2026 14:06
@sanki92
Copy link
Author

sanki92 commented Jan 13, 2026

@ghuls You're absolutely right, thanks for catching that!

I've applied your fix with one addition, pre-computing the async values before checking them:

const replies = data.replies ? await this.convertMessageReplies(data.replies) : undefined;
const editedBy = data.editedBy ? await this._cache.findImportedUser(data.editedBy) : undefined;
const reactions = data.reactions ? await this.convertMessageReactions(data.reactions) : undefined;

// Then:
...(replies && replies.length > 0 && { replies }),
...(editedBy && { editedBy }),
...(reactions && { reactions }),

This handles cases where cache lookups return null and avoids empty arrays.

Should work now for new imports without needing the database cleanup script!

@ghuls
Copy link

ghuls commented Jan 22, 2026

@sanki92 Tested and seems to work fine.

Only Slack files still can not be imported later.
I made a separate pull request for that to fix in the setImportFileRocketChatAttachment function itself:
#38291

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No history loads after slack import

3 participants