Skip to content

fix: keep shared receipts out of the folder the iOS share extension wipes #98980

Description

@mountiny

Problem

Two separate things destroy a shared receipt before its expense finishes uploading. The share extension wipes its own folder on every new share, so sharing a second receipt deletes the first one's file while that first request is still queued. The extension also writes files with .completeFileProtection, which makes them unreadable while the device is locked. In either case the request goes out without the receipt and the user gets a $0 expense with no error shown.

Shared receipts drop at 2.05% against a 0.59% iOS baseline — 101 of 4,938 between Aug 8 and Aug 18, 2026.

Solution

SubmitDetailsPage now moves the shared file into Documents/Receipts-Upload before reading it, using the same ReceiptStorage.adopt the camera and gallery paths already use, and points the draft receipt at the moved copy. The receipt therefore lives outside the folder the extension wipes, so a later share cannot delete it and a retry reads the durable copy rather than an emptied path.

ShareViewController drops the .completeFileProtection option so a locked device can still read the file, and checkFileExists logs the stat code so a permission failure stops looking like a deleted file. The protection fix that actually reaches iOS users ships in Mobile-Expensify#14063, because HybridApp builds Mobile-Expensify/iOS/SmartScanExtension; the copy in this PR only keeps the two from diverging.

PR

#98974

Companion iOS extension PR: https://github.com/Expensify/Mobile-Expensify/pull/14063

Issue OwnerCurrent Issue Owner: @ZhenjaHorbach

Metadata

Metadata

Labels

BugSomething is broken. Auto assigns a BugZero manager.ReviewingHas a PR in reviewWeeklyKSv2

Type

No type

Projects

Status
CRITICAL

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions