Skip to content

fix: prevent chatRef null errors when switching chats rapidly#894

Merged
Linhead merged 2 commits intodevfrom
fix/maintain-scroll-position-error
Jan 13, 2026
Merged

fix: prevent chatRef null errors when switching chats rapidly#894
Linhead merged 2 commits intodevfrom
fix/maintain-scroll-position-error

Conversation

@Linhead
Copy link
Collaborator

@Linhead Linhead commented Oct 8, 2025

Description

Fixed race condition errors occurring when rapidly switching between chats. The issue manifested as multiple TypeError: Cannot read properties of null errors for chatRef.value methods (maintainScrollPosition, scrollTo, scrollToBottom, isScrolledToBottom).

Root cause:

  • The Chat component uses :key="partnerId" in the parent view (Chat.vue line 5), which causes Vue to create a completely new component instance for each different partnerId
  • During component mount, onMounted schedules callbacks via nextTick() to execute after the next DOM update
  • When switching chats rapidly:
    1. Old component instance (Chat A) schedules nextTick callbacks
    2. Vue creates new component instance (Chat B) due to key change
    3. Old component instance unmounts, chatRef.value becomes null
    4. BUT: Previously scheduled nextTick callbacks from Chat A are still in the queue and execute, attempting to access the now-null chatRef.value
  • Additionally, setTimeout in fetchChatMessages continued running after component unmount, causing infinite error loops

Solution:

  1. Store and clear setTimeout ID in onBeforeUnmount to prevent delayed callbacks
  2. Add null safety checks in nextTick callbacks where chatRef.value is accessed (onMounted line 522, scrollBehavior lines 921-923)
  3. Use optional chaining (?.) for maintainScrollPosition() calls in finally blocks and recursive functions (lines 887, 894)

Related issue

Closes #893

External links (optional)

N/A

Screenshots or videos (optional)

N/A

Breaking changes

No breaking changes. This is a bug fix that improves stability.

How to test

  1. Login to the application
  2. Open multiple chats with different partners
  3. Rapidly switch back and forth between chats by clicking on them in the left sidebar (aim for <100ms between clicks)
  4. Open browser console and verify that no TypeError: Cannot read properties of null errors appear
  5. Test edge case: Switch chats immediately after sending a message
  6. Test edge case: Switch chats while messages are still loading

Expected outcome: No console errors, smooth chat transitions without crashes or infinite error loops.

Notes for reviewers

  • Key changes are in: src/components/Chat/Chat.vue

Checklist

  • Code is formatted
  • Tests added/updated (if needed) - Manual testing required, race conditions from rapid user interactions are difficult to reproduce reliably in unit tests
  • Documentation updated (if needed) - No documentation changes needed
  • Changes tested in all relevant environments

@Linhead Linhead requested a review from a team as a code owner October 8, 2025 08:32
@vercel
Copy link

vercel bot commented Oct 8, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
adamant-im Ready Ready Preview, Comment Jan 1, 2026 11:17am

@github-actions
Copy link

github-actions bot commented Oct 8, 2025

Deployed to https://msg-adamant-pr-894.surge.sh 🚀

Copy link
Member

@al-onyxprotocol al-onyxprotocol left a comment

Choose a reason for hiding this comment

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

Tested: https://adamant-lqle6zz2v-adamant-team.vercel.app
Chrome on macOS
Test ADM account

Test result: Failed
I don't see Cannot read properties of null in Console, but I see Element not found when switching between chats.

image

@al-onyxprotocol al-onyxprotocol added bug Something isn't working JavaScript Frontend or backend code in JavaScript Vue Frontend features or fixes primarily in Vue.js labels Oct 10, 2025
@Linhead
Copy link
Collaborator Author

Linhead commented Oct 13, 2025

@al-onyxprotocol
I looked through the code and found out that the warning on your screen handles and invokes manually by developer's code (take a look at screenshot). That's why I think it's expected behavior or at least that issue is not related to this one. And I checked it on the dev branch and ensures that this warning appears sometimes on the dev branch as well. So my fix is not the cause of this behavior
image

@dev-adamant-im
Copy link
Member

I looked through the code and found out that the warning on your screen handles and invokes manually by developer's code (take a look at screenshot)

Hey,
It looks like a debug message. Am I right? When does the Element not found happen from user perspective?

We can:

@S-FrontendDev @graycraft @Linhead What do you think?

@Linhead
Copy link
Collaborator Author

Linhead commented Jan 1, 2026

@dev-adamant-im @bludnic
I checked if block else-console.warn() was required and made a conclusion that it's useless and apparently left during development. So I removed this block from the code and additionally did refactor codebase of this component to composition API with script setup.

@adamantmm
Copy link
Member

@Linhead
Let's merge it.

@Linhead Linhead merged commit ebf282b into dev Jan 13, 2026
4 checks passed
@github-actions
Copy link

Successfully tore down https://msg-adamant-pr-894.surge.sh 🥲

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

Labels

bug Something isn't working JavaScript Frontend or backend code in JavaScript Vue Frontend features or fixes primarily in Vue.js

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Get Uncaught (in promise) TypeError: Cannot read properties of null (reading 'maintainScrollPosition')

6 participants