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-09-02] Android - Attachment - Broken image thumbnail is shown when uploading attachment #99490
👋 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: App deploy blocker (Android) — no Expensify/App PR identified as the cause; symptoms point to the native app layer Causing PR: None identified in Expensify/App (Low confidence in any App-side PR) Related Issues: None
Recommendation: NEEDS INVESTIGATION
Every attachment-flow change in the 9.4.61 release was reviewed and none affect the plain-image chat-upload rendering path; the Android-only broken local thumbnail points at the native app layer, which needs a separate internal investigation.
Assigned: No PR-author assignment — no App-repo PR reached medium confidence as the cause. Labels: No change. Keeping DeployBlockerCash (Android App deploy is genuinely blocked; bug is staging-only / not reproducible in production, so removal is not warranted). No web DeployBlocker label is present, which is correct.
📋 Detailed Analysis
What the bug is
Sending a plain image to any chat on Android shows a broken thumbnail while the attachment uploads. Android App only; not reproducible in production; reproducible on staging 9.4.61-0. A plain chat image has no transaction, so it renders through the generic image path (AttachmentView image branch / Image), not any receipt/eReceipt path.
App-repo PRs reviewed and ruled out
The only 9.4.61 PRs that touch the attachment/upload surface do not alter the plain-image rendering path:
AttachmentModalBaseContent: the new behavior is gated behind confirmLeavesScreen, which only the new Concierge picker sets. The chat flow uses the default (false) → identical onClose() + requestAnimationFrame(confirm) behavior as before.
ReportAddAttachmentModalContent: reads confirmLeavesScreen from context; undefined for the chat flow → unchanged.
AttachmentPickerWithMenuItems: pure style refactor of the "+" button column (composerButtonColumn/composerButtonStack); no image involved.
normalizeFileObject: inert local-variable rename (isNativePlatform → isNative); no behavior change.
AttachmentView/index.tsx (distance eReceipt commits + a revert) — every added/removed branch is gated behind isDistanceRequest(transaction). Plain chat images have no transaction, so these branches are skipped.
fix: cut out text on android #99069 (react-native Android patch) — patches TextLayoutManager text-width measurement on Android 15+ only; affects text wrapping, not image rendering.
The regression is (a) Android-App-only and (b) a failure to render a local image URI during upload — a platform-specific rendering concern. No App-repo change in this release touches that path. This release also advanced the native submodule, and a native-layer change is the most consistent explanation. That code is internal, so a separate internal investigation is needed to confirm the root cause and the fix location (revert vs. forward-fix on the native side).
[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
Test:
Launch the Expensify app (Android / iOS native).
Open any chat.
Send an image to the chat.
Verify the image renders the actual image (not a broken-image placeholder/icon) while the attachment is uploading.
Verify the image continues to display correctly after the upload completes.
If there are posts on the PR or issue that reference a regression or deploy blocker, C+ posts on the issue and confirms regression (which will reduce pay by 50%) or provides reasoning why they shouldn’t be considered. If the C+ doesn’t update the issue, the contributor manager making the payment will assume any mention of a regression or deploy blockers reduces the issue amount.
@mallenexpensify I’m not sure I understand what you mean, so let me summarize again: this PR fixes the regression introduced by PR #96531 (And I’m not C+ on this PR either). This PR does not introduce any new regressions.
Thanks for context @linhvovan29546 . I noticed `Deploy Blocker' mentioned here and also that it came from a regression. With paying so many issues it can take time to dig around to get details, it's helpful to have them on the issue I'm paying.
Activity
applause-bot commentedon Aug 25, 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/cac61e637136611ec75a0ec9cd40e82cd36c9137740b799e8e142b8d69c6405d
github-actions commentedon Aug 25, 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 Aug 25, 2026
Triggered auto assignment to @Gonals (
DeployBlockerCash), see https://stackoverflowteams.com/c/expensify/questions/9980/ for more details.melvin-bot commentedon Aug 25, 2026
💬 A slack conversation has been started in #expensify-open-source
MelvinBot commentedon Aug 25, 2026
🔍 Investigation Summary
Classification: App deploy blocker (Android) — no
Expensify/AppPR identified as the cause; symptoms point to the native app layerCausing PR: None identified in
Expensify/App(Low confidence in any App-side PR)Related Issues: None
Recommendation: NEEDS INVESTIGATION
Every attachment-flow change in the 9.4.61 release was reviewed and none affect the plain-image chat-upload rendering path; the Android-only broken local thumbnail points at the native app layer, which needs a separate internal investigation.
Assigned: No PR-author assignment — no App-repo PR reached medium confidence as the cause.
Labels: No change. Keeping
DeployBlockerCash(Android App deploy is genuinely blocked; bug is staging-only / not reproducible in production, so removal is not warranted). No webDeployBlockerlabel is present, which is correct.📋 Detailed Analysis
What the bug is
Sending a plain image to any chat on Android shows a broken thumbnail while the attachment uploads. Android App only; not reproducible in production; reproducible on staging 9.4.61-0. A plain chat image has no transaction, so it renders through the generic image path (
AttachmentViewimage branch /Image), not any receipt/eReceipt path.App-repo PRs reviewed and ruled out
The only 9.4.61 PRs that touch the attachment/upload surface do not alter the plain-image rendering path:
AttachmentModalBaseContent,ReportAddAttachmentModalContent,AttachmentPickerWithMenuItems,FileUtils.normalizeFileObject.AttachmentModalBaseContent: the new behavior is gated behindconfirmLeavesScreen, which only the new Concierge picker sets. The chat flow uses the default (false) → identicalonClose()+requestAnimationFrame(confirm)behavior as before.ReportAddAttachmentModalContent: readsconfirmLeavesScreenfrom context; undefined for the chat flow → unchanged.AttachmentPickerWithMenuItems: pure style refactor of the "+" button column (composerButtonColumn/composerButtonStack); no image involved.normalizeFileObject: inert local-variable rename (isNativePlatform→isNative); no behavior change.AttachmentView/index.tsx(distance eReceipt commits + a revert) — every added/removed branch is gated behindisDistanceRequest(transaction). Plain chat images have no transaction, so these branches are skipped.TextLayoutManagertext-width measurement on Android 15+ only; affects text wrapping, not image rendering.Why this looks native, not App
The regression is (a) Android-App-only and (b) a failure to render a local image URI during upload — a platform-specific rendering concern. No App-repo change in this release touches that path. This release also advanced the native submodule, and a native-layer change is the most consistent explanation. That code is internal, so a separate internal investigation is needed to confirm the root cause and the fix location (revert vs. forward-fix on the native side).
Verification performed
production...stagingcompare and grepped for image/attachment/composer/onyx/report rendering paths.normalizeFileObjectat the merge commit to confirm the rename is inert.AttachmentViewandAttachmentModalBaseContentchanges do not affect the plain-image (no-transaction) chat path.view run
melvin-bot commentedon Aug 26, 2026
Triggered auto assignment to Contributor-plus team member for initial proposal review - @linhvovan29546 (
External)melvin-bot commentedon Aug 26, 2026
Unable to auto-create job on Upwork. The BZ team member should create it manually for this issue.
28 remaining items
linhvovan29546 commentedon Aug 31, 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: https://github.com/Expensify/App/pull/96531/changes#r3892778000
[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
Test:
Do we agree 👍 or 👎
melvin-bot commentedon Sep 1, 2026
Triggered auto assignment to @mallenexpensify (
Awaiting Payment)melvin-bot commentedon Sep 1, 2026
Payment Summary
Resolving PRs:
[CP Staging] Fix broken Android upload thumbnail by adding file:// scheme to cached local source #99546
Reviewer: @linhvovan29546 owed $250 via NewDot
BugZero Checklist (@mallenexpensify)
mallenexpensify commentedon Sep 3, 2026
@linhvovan29546 from the C+ doc
linhvovan29546 commentedon Sep 4, 2026
@mallenexpensify I’m not sure I understand what you mean, so let me summarize again: this PR fixes the regression introduced by PR #96531 (And I’m not C+ on this PR either). This PR does not introduce any new regressions.
mallenexpensify commentedon Sep 4, 2026
Payment Summary
Contributor+: @linhvovan29546 due $250 via NewDot
Thanks for context @linhvovan29546 . I noticed `Deploy Blocker' mentioned here and also that it came from a regression. With paying so many issues it can take time to dig around to get details, it's helpful to have them on the issue I'm paying.
twisterdotcom commentedon Sep 5, 2026
$250 approved for @linhvovan29546 in Report ID: R00K5qdjoZdN.
Zapier Logs
Run ID: 00040eee-6e20-ab5d-8bb1-e87d78e8bf54SO: https://stackoverflowteams.com/c/expensify/questions/7582