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-10-19] Spend - Amount is out of view when merging reports with long name #100493
Version Number: 9.4.73-0 Reproducible in staging?: Yes Reproducible in production?: N/A - new feature, doesn't exist in prod If this was caught during regression testing, add the test name, ID and link from BrowserStack:#95658 Email or phone of affected tester (no customers):[email protected] Issue reported by: Applause Internal Team Bug source: Exploratory - Significant User Experience Deterioration Device used: Mac 26.5 / Chrome App Component: Search
Action Performed:
Go to staging.new.expensify.com
Go to workspace chat.
Create two reports with an expense each. One of the expenses must have long report title (eg, sjdoijsdnodjsoinsjdiodnsjiodsjoijsjdoijsdnodjsoinsjdiodnsjiodsjoijsjdoijsdnodjsoinsjdiodnsjiodsjoijsjdoijsdnodjsoinsjdiodnsjiodsjoijsjdoijsdnodjsoinsjdiodnsjiodsjoijsjdoijsdnodjsoinsjdiodnsjiodsjoijsjdoijsdnodjsoinsjdiodnsjiodsjoij).
Go to Spend > Reports.
Select both reports via checkbox.
Click dropdown menu > Merge reports.
Expected Result:
Amount will not be out of view when merging reports.
👋 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: #95658 - "feat: implement Merge Reports RHP and action menu" by @dmkt9 (High confidence) Related Issues: #94873, #94874 (the issues fixed by the causing PR)
Recommendation: ROLL FORWARD
The layout flaw is a 3-line style problem in one shared row component, while a revert would back out an entire feature (28 files, new route/screen, navigation config, mergeReports wiring, 10 language files). Fixing forward is far lower risk than reverting.
Assigned: @dmkt9 (PR author), @Gonals and @situchan (approving reviewers) from #95658 — already assigned by Melvin. Labels: No changes. DeployBlockerCash stays (App-side fix required). DeployBlocker was not present, so nothing to remove.
The report-name Text is itself the flex item. On web, react-native-web gives View a min-width: 0 reset but notText, so the name keeps min-width: auto, whose used value for a flex item is its content-based minimum size — for a single unbreakable 300-character word that is the full width of the word. flex: 1 (flex-basis: 0%) cannot shrink it below that floor, and min-width beats the max-width: 100% that numberOfLines > 1 adds, so the row overflows and pushes the flexShrink0 amount out of the visible area. The default overflow-wrap: break-word does not help here: per spec it does not reduce min-content size (only word-break/overflow-wrap: anywhere do). Note that numberOfLines > 1 in RNW 0.21 applies overflow: clip, which is not a scroll container, so it does not zero out the automatic minimum size the way overflow: hidden would.
Minimal fix — move flex1 onto a View wrapper (a View gets min-width: 0, and Yoga on native is unaffected), matching the existing styles.optionItemAvatarNameWrapper ({minWidth: 0, flex: 1}) idiom used for the same problem in option rows:
Adding styles.breakWord to the name Text also works on its own (it lowers min-content to one character), but the wrapper is the pattern already used elsewhere in the app. The date/expense-count row directly below (L48-L51) has the identical shape and should get the same treatment for consistency, even though those strings are short today.
📋 Detailed Analysis
Evidence
#95658 (merged 2026-09-04, item 47 in the current checklist) is the only PR in this release that builds the Merge reports flow: it adds the route/screen SearchReportsMergeReports.tsx, the MERGE_REPORTS_SEARCH_RHP screen, the Merge reports bulk action in useSearchBulkActions, and the report-selection row SearchMergeReportsListItem.tsx. The reproduction steps go through exactly that flow, and Applause confirms it does not exist in production, which is why this is staging-only.
No other PR in the checklist touches the merge-reports selection list. Nothing else in the release explains a name/amount row that only exists in the new RHP.
The new row component SearchMergeReportsListItem.tsx#L58-L86 reuses ExpenseReportListItemRowNarrow unconditionally (not behind isLargeScreenWidth, unlike ExpenseReportListItem.tsx#L509-L517), and squeezes it further by putting a RadioButton next to it in the same row. That is what surfaces the flaw on desktop Chrome/Safari.
gh pr view 95658 --json files confirms the PR adds both SearchMergeReportsListItem.tsx and SearchReportsMergeReports.tsx and modifies ExpenseReportListItemRowNarrow.tsx.
Container chain checked end to end: pressable (selectionListPressableItemWrapper, flexDirection: row) → BaseListItem wrapper (flex1, flexColumn, alignItemsStretch) → merge row (flexRow, flex1, gap3) → View flex1 → narrow row. Every ancestor is a View, so each one gets RNW's min-width: 0 and shrinks correctly; the name Text is the only node in the chain with a min-content floor, which isolates the overflow to that element.
Platform match: native Yoga has no min-width: auto content floor, which is consistent with the PR's Android/iOS videos looking fine and the bug being reported only on Chrome/Safari.
Not verified in a browser (no browser available in this environment); the conclusion is from the markup plus [email protected]Text styles (textMultiLine: display: -webkit-box, maxWidth: 100%, overflow: clip) and CSS flexbox automatic-minimum-size behavior.
💡 Suggested AI code review rule
This bug looks like a recurring, mechanically detectable pattern, so it may be worth a coding-standards rule so the AI reviewer catches the next one. Proposed for Expensify/App:
Rule:UI-4 Constrain flexible text with a minWidth: 0 wrapper, not flex1 on Text
Condition: flag a <Text> that renders user-generated content, carries styles.flex1 (or flexShrink) directly, and is a flex-row sibling of content that must stay visible (e.g. a styles.flexShrink0 amount). Wrap the text in a View that owns the flex1 (see styles.optionItemAvatarNameWrapper), or add styles.breakWord.
Why: on web, react-native-web resets min-width: 0 on View but not on Text, so a Text flex item keeps a min-content floor. A single long unbreakable string then refuses to shrink and pushes its siblings out of view — numberOfLines does not save it, because min-width overrides the max-width: 100% it adds. Incident: [Due for payment 2026-10-19] Spend - Amount is out of view when merging reports with long name #100493.
Search pattern: files containing styles.flexShrink0 that also contain <Text with styles.flex1 in its style array — grep -rln "styles.flexShrink0" src --include=*.tsx | xargs grep -n "styles.flex1" (~4 files today, plus ~25 <Text ... styles.flex1> sites overall).
The full rule file, with the ❌/✅ code inline in Expensify/App's coding-standards format, would go in Expensify/App itself (.claude/skills/coding-standards/rules/ui-4-*.md + a UI-4 index entry). If it's worth adding, a maintainer can open it there as a draft PR.
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.7-3 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:
The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the Contributor+ 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]. If no checklist is needed for this issue, you can click: [no checklist button]
changed the title [-]Spend - Amount is out of view when merging reports with long name[/-][+][Due for payment 2026-10-19] Spend - Amount is out of view when merging reports with long name[/+]on Oct 19, 2026
Activity
applause-bot commentedon Sep 7, 2026
While Applause doesn't embed attachments for this bug, here are the links for quick view:
https://platform.applause.com/services/links/v1/external/81eb4bd8ed3f095f426cc843f7ca2ca5e0670a997f3bec026f7441c3f2e5947d
melvin-bot commentedon Sep 7, 2026
You have been assigned to this deploy blocker because you recently merged this PR: #95658
github-actions commentedon Sep 7, 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:
melvin-bot commentedon Sep 7, 2026
@Gonals @situchan you have been assigned to this deploy blocker because you reviewed the offending PR: #95658
melvin-bot commentedon Sep 7, 2026
@dmkt9 you have been assigned to this deploy blocker because you authored the offending PR: #95658
melvin-bot commentedon Sep 7, 2026
💬 A slack conversation has been started in #expensify-open-source
MelvinBot commentedon Sep 7, 2026
🔍 Investigation Summary
Classification: Frontend bug
Causing PR: #95658 - "feat: implement Merge Reports RHP and action menu" by @dmkt9 (High confidence)
Related Issues: #94873, #94874 (the issues fixed by the causing PR)
Recommendation: ROLL FORWARD
The layout flaw is a 3-line style problem in one shared row component, while a revert would back out an entire feature (28 files, new route/screen, navigation config,
mergeReportswiring, 10 language files). Fixing forward is far lower risk than reverting.Assigned: @dmkt9 (PR author), @Gonals and @situchan (approving reviewers) from #95658 — already assigned by Melvin.
Labels: No changes.
DeployBlockerCashstays (App-side fix required).DeployBlockerwas not present, so nothing to remove.Root cause and suggested fix
The name/amount row lives in
ExpenseReportListItemRowNarrow.tsx#L39-L47:The report-name
Textis itself the flex item. On web,react-native-webgivesViewamin-width: 0reset but notText, so the name keepsmin-width: auto, whose used value for a flex item is its content-based minimum size — for a single unbreakable 300-character word that is the full width of the word.flex: 1(flex-basis: 0%) cannot shrink it below that floor, andmin-widthbeats themax-width: 100%thatnumberOfLines > 1adds, so the row overflows and pushes theflexShrink0amount out of the visible area. The defaultoverflow-wrap: break-worddoes not help here: per spec it does not reduce min-content size (onlyword-break/overflow-wrap: anywheredo). Note thatnumberOfLines > 1in RNW 0.21 appliesoverflow: clip, which is not a scroll container, so it does not zero out the automatic minimum size the wayoverflow: hiddenwould.Minimal fix — move
flex1onto aViewwrapper (aViewgetsmin-width: 0, and Yoga on native is unaffected), matching the existingstyles.optionItemAvatarNameWrapper({minWidth: 0, flex: 1}) idiom used for the same problem in option rows:Adding
styles.breakWordto the nameTextalso works on its own (it lowers min-content to one character), but the wrapper is the pattern already used elsewhere in the app. The date/expense-count row directly below (L48-L51) has the identical shape and should get the same treatment for consistency, even though those strings are short today.📋 Detailed Analysis
Evidence
SearchReportsMergeReports.tsx, theMERGE_REPORTS_SEARCH_RHPscreen, theMerge reportsbulk action inuseSearchBulkActions, and the report-selection rowSearchMergeReportsListItem.tsx. The reproduction steps go through exactly that flow, and Applause confirms it does not exist in production, which is why this is staging-only.SearchMergeReportsListItem.tsx#L58-L86reusesExpenseReportListItemRowNarrowunconditionally (not behindisLargeScreenWidth, unlikeExpenseReportListItem.tsx#L509-L517), and squeezes it further by putting aRadioButtonnext to it in the same row. That is what surfaces the flaw on desktop Chrome/Safari.productionbranch of the shared file (the only delta from feat: implement Merge Reports RHP and action menu #95658 is addingstyles.cursorPointer), so this is a latent flaw in shared narrow-row code that feat: implement Merge Reports RHP and action menu #95658 newly made reachable in the desktop RHP. It is still an App-side fix, soDeployBlockerCashstays, and feat: implement Merge Reports RHP and action menu #95658 remains the PR that makes it block this deploy.Verification
src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowNarrow.tsx(name + amount row), reached viasrc/components/Search/SearchList/ListItem/SearchMergeReportsListItem.tsx→src/pages/Search/SearchReportsMergeReports.tsx.gh pr view 95658 --json filesconfirms the PR adds bothSearchMergeReportsListItem.tsxandSearchReportsMergeReports.tsxand modifiesExpenseReportListItemRowNarrow.tsx.selectionListPressableItemWrapper,flexDirection: row) →BaseListItemwrapper (flex1,flexColumn,alignItemsStretch) → merge row (flexRow,flex1,gap3) →View flex1→ narrow row. Every ancestor is aView, so each one gets RNW'smin-width: 0and shrinks correctly; the nameTextis the only node in the chain with a min-content floor, which isolates the overflow to that element.min-width: autocontent floor, which is consistent with the PR's Android/iOS videos looking fine and the bug being reported only on Chrome/Safari.[email protected]Textstyles (textMultiLine:display: -webkit-box,maxWidth: 100%,overflow: clip) and CSS flexbox automatic-minimum-size behavior.💡 Suggested AI code review rule
This bug looks like a recurring, mechanically detectable pattern, so it may be worth a coding-standards rule so the AI reviewer catches the next one. Proposed for
Expensify/App:UI-4Constrain flexible text with aminWidth: 0wrapper, notflex1onText<Text>that renders user-generated content, carriesstyles.flex1(orflexShrink) directly, and is a flex-row sibling of content that must stay visible (e.g. astyles.flexShrink0amount). Wrap the text in aViewthat owns theflex1(seestyles.optionItemAvatarNameWrapper), or addstyles.breakWord.react-native-webresetsmin-width: 0onViewbut not onText, so aTextflex item keeps a min-content floor. A single long unbreakable string then refuses to shrink and pushes its siblings out of view —numberOfLinesdoes not save it, becausemin-widthoverrides themax-width: 100%it adds. Incident: [Due for payment 2026-10-19] Spend - Amount is out of view when merging reports with long name #100493.styles.flexShrink0that also contain<Textwithstyles.flex1in its style array —grep -rln "styles.flexShrink0" src --include=*.tsx | xargs grep -n "styles.flex1"(~4 files today, plus ~25<Text ... styles.flex1>sites overall).App/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowNarrow.tsx
Lines 39 to 47 in f29363e
View-wrapper version shown above, mirroringApp/src/styles/index.ts
Lines 2123 to 2126 in f29363e
The full rule file, with the ❌/✅ code inline in
Expensify/App's coding-standards format, would go inExpensify/Appitself (.claude/skills/coding-standards/rules/ui-4-*.md+ aUI-4index entry). If it's worth adding, a maintainer can open it there as a draft PR.17 remaining items
melvin-bot commentedon Oct 13, 2026
@situchan / @dmkt9
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.7-3 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:
The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the Contributor+ 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]. If no checklist is needed for this issue, you can click: [no checklist button]
Gonals commentedon Oct 15, 2026
Should be done. Closing
situchan commentedon Oct 19, 2026
I believe we're eligible for payment since this bug existed in production and we fixed this.
This was production bug, not caused by our PR
[-]Spend - Amount is out of view when merging reports with long name[/-][+][Due for payment 2026-10-19] Spend - Amount is out of view when merging reports with long name[/+]melvin-bot commentedon Oct 19, 2026
Triggered auto assignment to @mallenexpensify (
Awaiting Payment)melvin-bot commentedon Oct 19, 2026
Payment Summary
Resolving PRs:
Fix regressions with merging reports #101034
Reviewer: @situchan owed $175 via NewDot
Assignee: @dmkt9 requires payment (Needs manual offer from BZ)
BugZero Checklist (@mallenexpensify)