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-28] [$175] Concierge - Image appears cut on its preview on the Concierge RHP #103533
Version Number: 9.5.6-0 Reproducible in staging?: Yes Reproducible in production?: Yes If this was caught during regression testing, add the test name, ID and link from BrowserStack:#102937 Email or phone of affected tester (no customers):gatantm+697@gmail.com Issue reported by: Applause Internal Team Bug source: Exploratory - Significant User Experience Deterioration Device used: MacOS Safari App Component: Chat Report View
Action Performed:
Launch new Expensify logged in
Open any chat
Click on. the Concierge icon on top left
Click on the plus icon on the RHP chat > Add attachment
Select a vertical or not very wide image (or the one added on the report)
The cut-off image is the message thumbnail in the Concierge side panel, not the upload preview. The thumbnail is wider than the space the side panel has for message content.
useThumbnailDimensions.ts:19-20 picks a fixed thumbnail size from shouldUseNarrowLayout: 250px when narrow, 350px when wide. On wide web, the side panel is not a narrow layout. It is not inside the RHP navigator or a right-docked modal, so shouldUseNarrowLayout is false and the thumbnail gets the 350px wide-screen size.
The side panel is 375px wide (variables.ts:113). After the chat item padding and the avatar column, about 282px is left for content. ThumbnailImage.tsx:140-142 applies the size with overflowHidden and no maxWidth, so the right side is clipped.
This happens to any image message in the side panel whose thumbnail is wider than about 282px. It is not specific to the thread's parent message. A normal RHP thread is not affected because the RHP counts as a narrow layout and uses 250px.
What changes do you think we should make in order to solve the problem?
In useThumbnailDimensions, treat the side panel as a narrow layout. Use useIsInSidePanel() and pick the small-screen size when shouldUseNarrowLayout || isInSidePanel is true. HeaderView.tsx:265 already uses the same pattern. Thumbnails in the side panel then use 250px, which fits. This also fixes video previews, which use the same hook.
What alternative solutions did you explore? (Optional)
Add maxWidth: '100%' to the thumbnail size wrapper in ThumbnailImage, so a thumbnail can never be wider than its container. This is a good extra safeguard, but it has not been tested with aspectRatio on web.
Investigation notes
The issue screenshot shows the clipped image inside the side panel's thread view ("Thread" → image → "Replies"). The upload preview modal itself is not affected.
I confirmed the root cause by reading the code. I could not reproduce it live because the dev test environment failed to sign in.
Next Steps for Contributor+ team: To accept:@MelvinBot implement [this](https://github.com/Expensify/App/issues/103533) to create a draft PR. To refine:@MelvinBot <your feedback> To reject: Explain why you are rejecting Melvin's proposal.
changed the title [-]Concierge - Image appears cut on its preview on the Concierge RHP[/-][+][$175] Concierge - Image appears cut on its preview on the Concierge RHP[/+]on Oct 8, 2026
Please re-state the problem that we are trying to solve in this issue.
On wide desktop viewports, an image attachment message preview displayed inside the Concierge Right Hand Panel (RHP) side panel overflows the message column width and appears cut off on the right edge.
What is the root cause of that problem?
In src/hooks/useThumbnailDimensions.ts:19-20, image thumbnail dimensions are chosen based solely on shouldUseNarrowLayout:
On desktop screens, shouldUseNarrowLayout evaluates to false.
Consequently, fixedDimension is assigned CONST.THUMBNAIL_IMAGE.WIDE_SCREEN.SIZE (350px).
However, the side panel (SidePanelReport) has a fixed container width of 375px (variables.sidePanelWidth). Accounting for the chat item padding (20px horizontal) and avatar column spacing, the available message content width is under 300px.
Because the thumbnail width is fixed to 350px, the image container overflows its parent boundary and is clipped by the panel border.
What changes do you think we should make in order to solve the problem?
The Concierge side panel wraps its inner ReportScreen inside IsInSidePanelContext. We can consume this existing context via useIsInSidePanel inside useThumbnailDimensions:
When rendered inside the Concierge side panel, isInSidePanel is true, so fixedDimension adopts CONST.THUMBNAIL_IMAGE.SMALL_SCREEN.SIZE (250px), matching the narrow phone column layout.
In the main desktop chat pane, isInSidePanel is false, so wide desktop attachments remain rendered at full 350px width as expected.
This also automatically protects video preview thumbnails and image renderers that share useThumbnailDimensions.
What alternative solutions did you explore? (Optional)
Setting CSS maxWidth: '100%' on the inner image: Doesn't scale the aspect-ratio sized container correctly, causing letterboxing or parent overflow since the inner wrapper retains fixed 350px width.
Forcing shouldUseNarrowLayout globally in SidePanelReport: Undesirable because it alters other responsive behaviors (such as header action menus) across the side panel.
Tests
On desktop web or desktop app, open a chat with Concierge in the side panel (RHP).
Send or view an image attachment (landscape and portrait).
Verify that the image preview stays neatly within the message column without overflowing or cutting off.
Open the same chat in the main viewport and verify the image expands to standard desktop size (350px).
In src/hooks/useThumbnailDimensions.ts, thumbnail sizes are calculated using a binary check on shouldUseNarrowLayout:
On wide viewports (desktop and macOS Safari), shouldUseNarrowLayout is false, which sets fixedDimension to CONST.THUMBNAIL_IMAGE.WIDE_SCREEN.SIZE (350px).
When width > height, useThumbnailDimensions assigns {width: 350, aspectRatio} without constraining against the available container width (maxWidth: '100%').
However, the Concierge Right Hand Panel (SidePanelReport) has a fixed panel width of 375px (variables.sidePanelWidth). After accounting for message item horizontal padding (40px) and avatar margins (12px), the available column width inside the message item is ~323px.
Because width: 350px exceeds the ~323px column width and lacks container bounding (maxWidth: '100%'), the thumbnail overflows its parent bounds and gets clipped by the 27px overflow boundary on the right edge.
What changes do you think we should make in order to solve the problem?
To solve this comprehensively and prevent similar clipping across all current and future narrow desktop containers (such as the Concierge side panel, thread previews, and split layouts):
In ThumbnailImage.tsx, apply styles.mw100 (maxWidth: '100%') to the thumbnail dimension styles when shouldDynamicallyResize is active.
When combined with aspectRatio, maxWidth: '100%' ensures that even on wide screens, if the image is placed inside a container narrower than 350px (such as the 323px Concierge side panel column), the container automatically scales down to fit the column width without clipping the right edge.
When shouldUseNarrowLayout || isInSidePanel is true, set fixedDimension to CONST.THUMBNAIL_IMAGE.SMALL_SCREEN.SIZE (250px).
This aligns the side panel with phone column sizing standards (where available width is similarly 375px), ensuring optimal visual balance for both landscape and portrait thumbnails.
Combining both changes ensures that thumbnails adopt the proportional 250px standard in the side panel while structurally guaranteeing that any image preview can never overflow its parent container width across any view.
Unit Tests:
Add a unit test in tests/unit/useThumbnailDimensionsTest.ts validating:
When rendered within IsInSidePanelContext, the hook selects the small-screen preset (250px) on wide viewports.
Outside the side panel on wide viewports, it retains standard desktop sizing (350px).
What alternative solutions did you explore? (Optional)
Forcing shouldUseNarrowLayout globally inside SidePanelReport: Rejected because changing the global responsive layout flag alters other header, navigation, and modal behaviors across the entire report screen.
Applying maxWidth: '100%' only to the <img> tag without container constraints: Rejected because the wrapper View retains fixed 350px width, causing improper centering and container clipping.
Tests
On desktop (macOS Safari / Chrome), open any chat.
Click the Concierge icon to open the Concierge chat in the Right Hand Panel (side panel).
Click the attachment icon (+) > Add attachment, and select an image (both landscape and portrait).
Verify that the image preview renders completely inside the message column without any horizontal clipping on the right edge.
Open the same chat in the main center pane and verify the attachment preview displays at the standard desktop dimension (350px).
🤖 Draft PR created: #104288
Please mark it as "Ready for review" or ask me to do that for you when it is ready for review.
The fix follows the approved proposal: useThumbnailDimensions now uses the 250px small-screen size when it runs inside the Concierge side panel, so thumbnails fit. The main chat view keeps the 350px size. Unit tests, lint, typecheck, and the React Compiler check pass. I couldn't check the change in the browser because the automated test session loaded a blank page, so please confirm it manually.
[Contributor] The offending PR and associated issue have been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake.
[Contributor] If the regression was CRITICAL (e.g. interrupts a core flow) A discussion in #expensify-open-source has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner.
Link to discussion:
[Contributor] If it was decided to create a regression test for the bug, please propose the regression test steps using the template below to ensure the same bug will not reach production again.
Regression Test Proposal
Precondition:
Have a chat with Concierge that contains at least one image attachment (landscape or portrait)
Use a desktop browser with a wide viewport (so the side panel renders at full 375px width)
Test:
Open the app on desktop web
Click the Concierge icon (top left) to open the Concierge chat in the side panel
Send or view an image attachment in the side panel chat
Verify the image preview renders fully within the message column without any horizontal clipping on the right edge
Open the same Concierge chat in the main center pane and verify image attachments display at standard desktop size
changed the title [-][$175] Concierge - Image appears cut on its preview on the Concierge RHP[/-][+][Due for payment 2026-10-28] [$175] Concierge - Image appears cut on its preview on the Concierge RHP[/+]on Oct 21, 2026
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.15-3 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-10-28. 🎊
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]
Activity
applause-bot commentedon Oct 8, 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/dc3ddaa64be002e132d472a4560a75a2c0a97b13e9cb55b55c0d0349bdd690b5
https://platform.applause.com/services/links/v1/external/f86cd10b6f5aa1c32cedcfeca443060659823147255d6c93ad84180fff28b016
https://platform.applause.com/services/links/v1/external/11e28cfbec9f5b66b2781fbd1859df0f18707ab5ccfbf919a688edfc6ea7ace6
MelvinBot commentedon Oct 8, 2026
Proposal
What is the root cause of that problem?
The cut-off image is the message thumbnail in the Concierge side panel, not the upload preview. The thumbnail is wider than the space the side panel has for message content.
useThumbnailDimensions.ts:19-20picks a fixed thumbnail size fromshouldUseNarrowLayout: 250px when narrow, 350px when wide. On wide web, the side panel is not a narrow layout. It is not inside the RHP navigator or a right-docked modal, soshouldUseNarrowLayoutisfalseand the thumbnail gets the 350px wide-screen size.The side panel is 375px wide (
variables.ts:113). After the chat item padding and the avatar column, about 282px is left for content.ThumbnailImage.tsx:140-142applies the size withoverflowHiddenand nomaxWidth, so the right side is clipped.This happens to any image message in the side panel whose thumbnail is wider than about 282px. It is not specific to the thread's parent message. A normal RHP thread is not affected because the RHP counts as a narrow layout and uses 250px.
What changes do you think we should make in order to solve the problem?
In
useThumbnailDimensions, treat the side panel as a narrow layout. UseuseIsInSidePanel()and pick the small-screen size whenshouldUseNarrowLayout || isInSidePanelis true.HeaderView.tsx:265already uses the same pattern. Thumbnails in the side panel then use 250px, which fits. This also fixes video previews, which use the same hook.What alternative solutions did you explore? (Optional)
Add
maxWidth: '100%'to the thumbnail size wrapper inThumbnailImage, so a thumbnail can never be wider than its container. This is a good extra safeguard, but it has not been tested withaspectRatioon web.Investigation notes
useThumbnailDimensions.tshas not changed its logic since 2024, so this does not look like a recent regression. 102436: Concierge - RHP closes when dismissing an attachment with Esc or expanding a chart only changes Esc and history handling, not layout.Next Steps for Contributor+ team:
To accept:
@MelvinBot implement [this](https://github.com/Expensify/App/issues/103533)to create a draft PR.To refine:
@MelvinBot <your feedback>To reject: Explain why you are rejecting Melvin's proposal.
view run · no recording available
melvin-bot commentedon Oct 8, 2026
Triggered auto assignment to Contributor-plus team member for initial proposal review - @rojiphil (
External)[-]Concierge - Image appears cut on its preview on the Concierge RHP[/-][+][$175] Concierge - Image appears cut on its preview on the Concierge RHP[/+]melvin-bot commentedon Oct 8, 2026
Job added to Upwork: https://www.upwork.com/jobs/~022108319757049731349
yuvrajangadsingh commentedon Oct 8, 2026
withdrawing this, it went up before the issue had the
Help Wantedlabel. will come back if the label is added.jloa-dev commentedon Oct 9, 2026
Proposal
Please re-state the problem that we are trying to solve in this issue.
On wide desktop viewports, an image attachment message preview displayed inside the Concierge Right Hand Panel (RHP) side panel overflows the message column width and appears cut off on the right edge.
What is the root cause of that problem?
In
src/hooks/useThumbnailDimensions.ts:19-20, image thumbnail dimensions are chosen based solely onshouldUseNarrowLayout:shouldUseNarrowLayoutevaluates tofalse.fixedDimensionis assignedCONST.THUMBNAIL_IMAGE.WIDE_SCREEN.SIZE(350px).SidePanelReport) has a fixed container width of 375px (variables.sidePanelWidth). Accounting for the chat item padding (20px horizontal) and avatar column spacing, the available message content width is under 300px.What changes do you think we should make in order to solve the problem?
The Concierge side panel wraps its inner
ReportScreeninsideIsInSidePanelContext. We can consume this existing context viauseIsInSidePanelinsideuseThumbnailDimensions:In
src/hooks/useThumbnailDimensions.ts:isInSidePanelistrue, sofixedDimensionadoptsCONST.THUMBNAIL_IMAGE.SMALL_SCREEN.SIZE(250px), matching the narrow phone column layout.isInSidePanelisfalse, so wide desktop attachments remain rendered at full 350px width as expected.useThumbnailDimensions.What alternative solutions did you explore? (Optional)
maxWidth: '100%'on the inner image: Doesn't scale the aspect-ratio sized container correctly, causing letterboxing or parent overflow since the inner wrapper retains fixed 350px width.shouldUseNarrowLayoutglobally inSidePanelReport: Undesirable because it alters other responsive behaviors (such as header action menus) across the side panel.Tests
Contributor details
Your Expensify account email: jloa.dev@gmail.com
Upwork Profile Link: https://www.upwork.com/freelancers/~0163955a2ba22190aa
melvin-bot commentedon Oct 9, 2026
✅ Contributor details stored successfully. Thank you for contributing to Expensify!
camesenin commentedon Oct 9, 2026
Proposal
What is the root cause of that problem?
In
src/hooks/useThumbnailDimensions.ts, thumbnail sizes are calculated using a binary check onshouldUseNarrowLayout:shouldUseNarrowLayoutisfalse, which setsfixedDimensiontoCONST.THUMBNAIL_IMAGE.WIDE_SCREEN.SIZE(350px).width > height,useThumbnailDimensionsassigns{width: 350, aspectRatio}without constraining against the available container width (maxWidth: '100%').SidePanelReport) has a fixed panel width of 375px (variables.sidePanelWidth). After accounting for message item horizontal padding (40px) and avatar margins (12px), the available column width inside the message item is ~323px.width: 350pxexceeds the ~323px column width and lacks container bounding (maxWidth: '100%'), the thumbnail overflows its parent bounds and gets clipped by the 27px overflow boundary on the right edge.What changes do you think we should make in order to solve the problem?
To solve this comprehensively and prevent similar clipping across all current and future narrow desktop containers (such as the Concierge side panel, thread previews, and split layouts):
Responsive Container Constraining (
src/components/ThumbnailImage.tsx):ThumbnailImage.tsx, applystyles.mw100(maxWidth: '100%') to the thumbnail dimension styles whenshouldDynamicallyResizeis active.aspectRatio,maxWidth: '100%'ensures that even on wide screens, if the image is placed inside a container narrower than 350px (such as the 323px Concierge side panel column), the container automatically scales down to fit the column width without clipping the right edge.Context-Aware Column Sizing (
src/hooks/useThumbnailDimensions.ts):useIsInSidePanel()insideuseThumbnailDimensions.ts(or optionally pass container constraint props):shouldUseNarrowLayout || isInSidePanelis true, setfixedDimensiontoCONST.THUMBNAIL_IMAGE.SMALL_SCREEN.SIZE(250px).Unit Tests:
tests/unit/useThumbnailDimensionsTest.tsvalidating:IsInSidePanelContext, the hook selects the small-screen preset (250px) on wide viewports.What alternative solutions did you explore? (Optional)
shouldUseNarrowLayoutglobally insideSidePanelReport: Rejected because changing the global responsive layout flag alters other header, navigation, and modal behaviors across the entire report screen.maxWidth: '100%'only to the<img>tag without container constraints: Rejected because the wrapperViewretains fixed 350px width, causing improper centering and container clipping.Tests
Contributor details
Your Expensify account email: camesenin@gmail.com
Upwork Profile Link: https://www.upwork.com/freelancers/~0170d6b02e9440e604
melvin-bot commentedon Oct 9, 2026
✅ Contributor details stored successfully. Thank you for contributing to Expensify!
14 remaining items
abzokhattab commentedon Oct 16, 2026
sure .. taking alook now
abzokhattab commentedon Oct 16, 2026
Going forward with melvin proposal as it fixes the root cause
🎀 👀 🎀 C+ reviewed
abzokhattab commentedon Oct 16, 2026
@MelvinBot implement this
melvin-bot commentedon Oct 16, 2026
Triggered auto assignment to @roryabraham, see https://stackoverflow.com/c/expensify/questions/7972 for more details.
MelvinBot commentedon Oct 16, 2026
🤖 Draft PR created: #104288
Please mark it as "Ready for review" or ask me to do that for you when it is ready for review.
The fix follows the approved proposal:
useThumbnailDimensionsnow uses the 250px small-screen size when it runs inside the Concierge side panel, so thumbnails fit. The main chat view keeps the 350px size. Unit tests, lint, typecheck, and the React Compiler check pass. I couldn't check the change in the browser because the automated test session loaded a blank page, so please confirm it manually.abzokhattab commentedon Oct 19, 2026
Contributor+ Checklist:
[Contributor] The offending PR and associated issue have been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake.
Link to the comment on the PR: Add Concierge to the Side Panel = Concierge Everywhere! #76277 (comment)
Link to the comment on the Issue: this comment
[Contributor] If the regression was CRITICAL (e.g. interrupts a core flow) A discussion in #expensify-open-source has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner.
Link to discussion:
[Contributor] If it was decided to create a regression test for the bug, please propose the regression test steps using the template below to ensure the same bug will not reach production again.
Regression Test Proposal
Precondition:
Test:
Do we agree 👍 or 👎
[-][$175] Concierge - Image appears cut on its preview on the Concierge RHP[/-][+][Due for payment 2026-10-28] [$175] Concierge - Image appears cut on its preview on the Concierge RHP[/+]melvin-bot commentedon Oct 21, 2026
@abzokhattab
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.15-3 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-10-28. 🎊
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]