You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Due for payment 2026-03-30] Task - Assignee avatar is inconsistent in task & assignee page #85532
Version Number: V9.3.39-0 Reproducible in staging?: Yes Reproducible in production?: No If this was caught during regression testing, add the test name, ID and link from BrowserStack:#85032 Email or phone of affected tester (no customers):dreamnitethedragon+yydyd373@gmail.com Issue reported by: Applause Internal Team Bug source: Exploratory - Significant User Experience Deterioration Device used: Redminote 10S Android 13 App Component: Other
Action Performed:
Launch app
Open self dm
Create a task entering existing user as assignee
Open the task
Open the assignee
Expected Result:
Assignee avatar must be consistent in task & assignee page.
Actual Result:
Assignee avatar is inconsistent in task & assignee page.
👋 Friendly reminder that deploy blockers are time-sensitive ⏱ issues! Check out the open `StagingDeployCash` deploy checklist to see the list of PRs included in this release, then work quickly to do one of the following:
Identify the pull request that introduced this issue and revert it.
Classification: Frontend bug Causing PR: #85032 - "fix: Assigned task appears hidden and assignee status not shown" by @nkdengineer (High confidence) Related Issues: #81714 (original issue that #85032 was fixing)
Recommendation: ROLL FORWARD
While PR #85032 can be cleanly reverted, rolling forward with a fix is the better approach because:
PR #85032 modified how optimistic personal details are handled when assigning tasks. The PR introduced tracking via the isOptimisticPersonalDetail flag to conditionally clear optimistic personal details on API success.
Problem: This logic incorrectly marks existing users as optimistic when their personal details simply haven't been loaded into the local allPersonalDetails object yet.
Flow of the bug:
User selects an existing user (who they haven't chatted with before) as task assignee
allPersonalDetails[accountID] is undefined/empty (not yet loaded)
The isOptimisticPersonalDetail flag should distinguish between "truly new user" vs "existing user whose details aren't loaded yet"
Recommended fix approach:
The fix should ensure that isOptimisticPersonalDetail is only set to true for genuinely new/optimistic users, not for existing users whose personal details happen to be unloaded. This might require checking additional signals (e.g., whether the user exists in the backend) or preserving the personal details differently.
Please re-state the problem that we are trying to solve in this issue.
When creating a task and assigning it to an existing user, the assignee's avatar is inconsistent between the task detail view and the assignee's page. This regression was introduced in staging by PR #85032.
What is the root cause of that problem?
PR #85032 changed getTaskAssigneeChatOnyxData in src/libs/ReportUtils.ts to only null out the assignee's personal details on API success for optimistic (new) users. For existing users, the null-out is now skipped.
The problem lies in setNewOptimisticAssignee (src/libs/actions/Task.ts:878-885). When called for an existing user (who has no 1:1 DM chat with the current user), it merges a partial personal details object (only 5 fields: accountID, avatar, displayName, login, isOptimisticPersonalDetail) into ONYXKEYS.PERSONAL_DETAILS_LIST via Onyx.merge.
setNewOptimisticAssignee merges partial personal details (with isOptimisticPersonalDetail: false for existing users)
On API success, the success callback skips the null (because isOptimisticPersonalDetail() returns false)
The backend response merges on top, but the partial optimistic data persists
The task view (via useReportActionAvatars at src/components/ReportActionAvatars/useReportActionAvatars.ts:128) reads personalDetails?.[id]?.avatar ?? FallbackAvatar
The profile page (via openPublicProfilePage) fetches fresh data from the server, updating the avatar
The inconsistency arises because the task view uses the locally-stored (potentially stale) avatar, while navigating to the assignee triggers a fresh server fetch that returns the canonical avatar.
What changes do you think we should make in order to solve the problem?
In setNewOptimisticAssignee (src/libs/actions/Task.ts:878-885), skip the Onyx.merge into PERSONAL_DETAILS_LIST when the user already exists (i.e., when isOptimisticPersonalDetail is false). The merge into personal details is only needed for truly new/optimistic users whose data doesn't exist in the store yet. For existing users, their personal details are already in PERSONAL_DETAILS_LIST and don't need to be overwritten with a partial object.
Specifically, wrap the existing Onyx.merge call at line 885 with a condition:
if (assigneePersonalDetails.isOptimisticPersonalDetail) {
Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, {[assigneePersonalDetails.accountID]: optimisticPersonalDetailsListAction});
}
This preserves the fix from PR #85032 (not nulling existing users on success) while preventing the partial overwrite that causes avatar inconsistency.
What alternative solutions did you explore? (Optional)
Make the optimistic object include ALL personal details fields — This would mean copying the full personal details into the optimistic object. While it would prevent data loss, it adds complexity and the merge is still unnecessary for existing users.
Keep the null-out but immediately re-merge the existing data — Overly complex and still has a brief flicker where data is null.
Next Steps for Contributor+ team: Reply with @MelvinBot implement this to create a draft PR, @MelvinBot <your feedback> to refine this analysis, or explain why you are rejecting Melvin's proposal.
@dangrous I checked this for a while. Currently, the bug is visible after our PR, but the RCA is not our PR. On production, the assignee is not displayed in the assignee page after assigning the task.
The RCA is
We still have another wrong code here, which clears the assignee from participants unexpectedly, even if it's not an optimistic user. Which causes useReportAvatars hook to return the wrong avatar (it returns the current user avatar because the assignee doesn't appear in the participant list of the report)
// BE will send a different participant. We clear the optimistic one to avoid duplicated entries
participants: {[assigneeAccountID]: null},
},
},
{
onyxMethod: Onyx.METHOD.MERGE,
Also found the backend problem. CreateTask report API doesn't create the chat report with the assignee, even if the param exists. Then when we open the assignee chat report which is created in optimistic data, not found error appears
changed the title [-]Task - Assignee avatar is inconsistent in task & assignee page[/-][+][Due for payment 2026-03-30] Task - Assignee avatar is inconsistent in task & assignee page[/+]on Mar 23, 2026
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.3.41-4 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:
@dukenv0307 The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the BugZero Checklist from here into a new comment on this GH and complete it. If you have the K2 extension, you can simply click: [this button]
Activity
melvin-bot commentedon Mar 17, 2026
You have been assigned to this deploy blocker because you recently merged this PR: #85032
melvin-bot commentedon Mar 17, 2026
💬 A slack conversation has been started in #expensify-open-source
github-actions commentedon Mar 17, 2026
👋 Friendly reminder that deploy blockers are time-sensitive ⏱ issues! Check out the open `StagingDeployCash` deploy checklist to see the list of PRs included in this release, then work quickly to do one of the following:
OSBotify commentedon Mar 17, 2026
🔍 Investigation Summary
Classification: Frontend bug
Causing PR: #85032 - "fix: Assigned task appears hidden and assignee status not shown" by @nkdengineer (High confidence)
Related Issues: #81714 (original issue that #85032 was fixing)
Recommendation: ROLL FORWARD
While PR #85032 can be cleanly reverted, rolling forward with a fix is the better approach because:
isOptimisticPersonalDetailflag is being set incorrectly for existing usersLabels: Keeping
DeployBlockerCash(App PR caused the issue, App deploy remains blocked)📋 Detailed Analysis
Evidence
PR #85032 modified how optimistic personal details are handled when assigning tasks. The PR introduced tracking via the
isOptimisticPersonalDetailflag to conditionally clear optimistic personal details on API success.Key changes in PR #85032:
isOptimisticPersonalDetailflag to personal detailsTaskAssigneeSelectorModal.tsxline 155:isOptimisticPersonalDetail: !allPersonalDetails?.[option?.accountID ?? CONST.DEFAULT_NUMBER_ID]ReportUtils.ts(only clears ifisOptimisticPersonalDetail(assigneeAccountID)returns true)Verification
src/libs/ReportUtils.ts,src/libs/actions/Task.ts,src/pages/tasks/TaskAssigneeSelectorModal.tsxRoot Cause
The bug occurs in
TaskAssigneeSelectorModal.tsxat line 155:Problem: This logic incorrectly marks existing users as optimistic when their personal details simply haven't been loaded into the local
allPersonalDetailsobject yet.Flow of the bug:
allPersonalDetails[accountID]is undefined/empty (not yet loaded)isOptimisticPersonalDetail: true(incorrectly)isOptimisticPersonalDetail(assigneeAccountID)which returnstrue{[assigneeAccountID]: null}Why this breaks:
isOptimisticPersonalDetailflag should distinguish between "truly new user" vs "existing user whose details aren't loaded yet"Recommended fix approach:
The fix should ensure that
isOptimisticPersonalDetailis only set totruefor genuinely new/optimistic users, not for existing users whose personal details happen to be unloaded. This might require checking additional signals (e.g., whether the user exists in the backend) or preserving the personal details differently.MelvinBot commentedon Mar 17, 2026
Proposal
Please re-state the problem that we are trying to solve in this issue.
When creating a task and assigning it to an existing user, the assignee's avatar is inconsistent between the task detail view and the assignee's page. This regression was introduced in staging by PR #85032.
What is the root cause of that problem?
PR #85032 changed
getTaskAssigneeChatOnyxDatainsrc/libs/ReportUtils.tsto only null out the assignee's personal details on API success for optimistic (new) users. For existing users, the null-out is now skipped.The problem lies in
setNewOptimisticAssignee(src/libs/actions/Task.ts:878-885). When called for an existing user (who has no 1:1 DM chat with the current user), it merges a partial personal details object (only 5 fields:accountID,avatar,displayName,login,isOptimisticPersonalDetail) intoONYXKEYS.PERSONAL_DETAILS_LISTviaOnyx.merge.Before PR #85032:
setNewOptimisticAssigneemerges partial personal details{[assigneeAccountID]: null})After PR #85032:
setNewOptimisticAssigneemerges partial personal details (withisOptimisticPersonalDetail: falsefor existing users)isOptimisticPersonalDetail()returnsfalse)useReportActionAvatarsatsrc/components/ReportActionAvatars/useReportActionAvatars.ts:128) readspersonalDetails?.[id]?.avatar ?? FallbackAvataropenPublicProfilePage) fetches fresh data from the server, updating the avatarThe inconsistency arises because the task view uses the locally-stored (potentially stale) avatar, while navigating to the assignee triggers a fresh server fetch that returns the canonical avatar.
What changes do you think we should make in order to solve the problem?
In
setNewOptimisticAssignee(src/libs/actions/Task.ts:878-885), skip theOnyx.mergeintoPERSONAL_DETAILS_LISTwhen the user already exists (i.e., whenisOptimisticPersonalDetailisfalse). The merge into personal details is only needed for truly new/optimistic users whose data doesn't exist in the store yet. For existing users, their personal details are already inPERSONAL_DETAILS_LISTand don't need to be overwritten with a partial object.Specifically, wrap the existing
Onyx.mergecall at line 885 with a condition:This preserves the fix from PR #85032 (not nulling existing users on success) while preventing the partial overwrite that causes avatar inconsistency.
What alternative solutions did you explore? (Optional)
Revert the
isOptimisticPersonalDetailcondition ingetTaskAssigneeChatOnyxData— This would re-introduce the original bug from issue [$250] Task - Assigned task appears hidden and assignee status not shown #81714 (task appearing hidden for existing users).Make the optimistic object include ALL personal details fields — This would mean copying the full personal details into the optimistic object. While it would prevent data loss, it adds complexity and the merge is still unnecessary for existing users.
Keep the null-out but immediately re-merge the existing data — Overly complex and still has a brief flicker where data is null.
Next Steps for Contributor+ team: Reply with @MelvinBot implement this to create a draft PR, @MelvinBot <your feedback> to refine this analysis, or explain why you are rejecting Melvin's proposal.
dangrous commentedon Mar 17, 2026
Can confirm, comes from #81714 PR. @nkdengineer I can't assign you here until you comment I guess? Not sure why I could for @dukenv0307
nkdengineer commentedon Mar 17, 2026
@dangrous I checked this for a while. Currently, the bug is visible after our PR, but the RCA is not our PR. On production, the assignee is not displayed in the assignee page after assigning the task.
The RCA is
participantsunexpectedly, even if it's not an optimistic user. Which causesuseReportAvatarshook to return the wrong avatar (it returns the current user avatar because the assignee doesn't appear in the participant list of the report)App/src/libs/ReportUtils.ts
Lines 10385 to 10398 in a57e04d
CreateTaskreport API doesn't create the chat report with the assignee, even if the param exists. Then when we open the assignee chat report which is created in optimistic data, not found error appearsScreen.Recording.2026-03-17.at.20.38.39.mov
To fix this issue, we only need to fix point 1
7 remaining items
dangrous commentedon Mar 20, 2026
We're on staging!
[-]Task - Assignee avatar is inconsistent in task & assignee page[/-][+][Due for payment 2026-03-30] Task - Assignee avatar is inconsistent in task & assignee page[/+]melvin-bot commentedon Mar 23, 2026
Reviewinglabel has been removed, please complete the "BugZero Checklist".melvin-bot commentedon Mar 23, 2026
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.3.41-4 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:
If no regressions arise, payment will be issued on 2026-03-30. 🎊
For reference, here are some details about the assignees on this issue:
melvin-bot commentedon Mar 23, 2026
@dukenv0307 The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the BugZero Checklist from here into a new comment on this GH and complete it. If you have the K2 extension, you can simply click: [this button]
melvin-bot commentedon Mar 23, 2026
Triggered auto assignment to @mallenexpensify (
Awaiting Payment)dukenv0307 commentedon Mar 24, 2026
No need for payment
dangrous commentedon Mar 24, 2026
Love it! I will close this out, anyone can ping if that's in error.