Skip to content

App crashes when swipe back from description and tap on it #98993

Closed

Description

@lanitochka17

If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!


Version Number: 9.4.56-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: #98808
Email or phone of affected tester (no customers): emady.syed1234+daddu@gmail.com
Issue reported by: Applause Internal Team
Bug source: Pull Request QA execution
Device used: iPhone 12 / iOS 26.3.1
App Component: Money Requests

Action Performed:

  1. Open App
  2. Create an expense
  3. Enter text in description field
  4. Swipe back and quickly tap on any field before discard pop up appears

Expected Result:

App should not crash.

Actual Result:

App crash when tap on any field.

Workaround:

Unknown

Platforms:

  • Android: App
  • Android: mWeb Chrome
  • iOS: App
  • iOS: mWeb Safari
  • iOS: mWeb Chrome
  • Windows: Chrome
  • MacOS: Chrome / Safari

Screenshots/Videos

Bug7237295_1787147957845.ScreenRecording_08-19-2026_18-56-30_1.mp4

Bug7237295_1787147966940!crash2.txt

View all open jobs on GitHub

Upwork Automation - Do Not Edit
Issue OwnerCurrent Issue Owner: @getusha

Activity

  1. added
    BugSomething is broken. Auto assigns a BugZero manager.
    on Aug 19, 2026
  2. MelvinBot commented on Aug 19, 2026

    @MelvinBot
    Contributor

    Proposal

    Root cause (Medium confidence)

    This is a native iOS crash in the discard-changes → re-focus path of the expense description step. It is not reproducible on web/Android by design, so it could not be verified in this run's web session — the fix needs iOS device testing.

    The flow:

    1. On the description step you type text, then iOS edge-swipe back. Because there are unsaved changes, useDiscardChangesConfirmation intercepts the removal via usePreventRemove and shows the discard modal. Showing the modal flips the field to editable={false}, which on iOS resigns the keyboard while RN's JS-side isFocused() still reports true.
    2. Tapping another field dismisses the modal as a non-confirm, so onCancel fires and calls focusComposerWithDelay(inputRef.current)(true, undefined, shouldForceKeyboardIfAlreadyFocused()). On iOS shouldForceKeyboardIfAlreadyFocused() returns true.
    3. Because the field still reports focused, this schedules a deferred native call — requestIdleCallback(() => KeyboardController.setFocusTo('current')) (native reloadInputViews + focus on iOS). Because the user tapped mid-transition, by the time the idle callback runs the screen is unmounting / the first responder is stale, so setFocusTo('current') runs against a detached native input and crashes.

    Note on PR #98808 (whose QA surfaced this): its only production change is Android-only (gating forceKeyboardIfAlreadyFocused off on Android). The iOS path is byte-identical before/after #98808, so #98808 did not introduce the crash — it just exercised the exact flow. The crashing iOS KeyboardController.setFocusTo('current') mechanism was introduced earlier by PR #97823 (the fix for Expensify/App#97604).

    Recommended fix

    Guard the deferred native focus so it no-ops when the input is no longer valid/focused or the screen is unmounting, in requestKeyboardForFocusedComposer/index.native.ts:

    • Inside the requestIdleCallback, re-check textInput?.isFocused?.() (and/or that the ref is still mounted) immediately before calling KeyboardController.setFocusTo('current'), and skip the call otherwise; wrap in a try/catch as a native-safety net.
    • Alternatively, in the description step's onCancel, only re-focus when the screen useIsFocused() is still true.
    Investigation details & confidence

    Next Steps for Contributor+ team:
    To accept: @MelvinBot implement [this](https://github.com/Expensify/App/issues/98993) to create a draft PR.
    To refine: @MelvinBot <your feedback>
    To reject: Explain why you are rejecting Melvin's proposal.


    view run

  3. added
    ExternalAdded to denote the issue can be worked on by a contributor
    on Aug 19, 2026
  4. melvin-bot commented on Aug 19, 2026

    @melvin-bot

    Triggered auto assignment to Contributor-plus team member for initial proposal review - @rojiphil (External)

  5. melvin-bot commented on Aug 19, 2026

    @melvin-bot
  6. melvin-bot commented on Aug 24, 2026

    @melvin-bot

    @rojiphil Eep! 4 days overdue now. Issues have feelings too...

  7. melvin-bot commented on Aug 26, 2026

    @melvin-bot

    @rojiphil 6 days overdue. This is scarier than being forced to listen to Vogon poetry!

  8. rojiphil commented on Aug 28, 2026

    @rojiphil
    Contributor

    I am unable to reproduce this issue

    98993-ios-hybrid-001.mp4
  9. getusha commented on Aug 28, 2026

    @getusha
    Contributor

    I was able to reproduce, taking over!

  10. mkhutornyi commented on Aug 28, 2026

    @mkhutornyi
    Contributor

    Looks like this is regression from #97823.
    This was reported within 7-day regression window.

    cc: @ikevin127

  11. 25 remaining items

  12. melvin-bot commented on Sep 10, 2026

    @melvin-bot

    @getusha Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!

  13. getusha commented on Sep 11, 2026

    @getusha
    Contributor

    Reviewing

  14. getusha commented on Sep 14, 2026

    @getusha
    Contributor

    Trying to reproduce on simulator.

  15. melvin-bot commented on Sep 16, 2026

    @melvin-bot

    @getusha this issue is now 4 weeks old, please consider:

    • Finding a contributor to fix the bug
    • Closing the issue if BZ has been unable to add the issue to a VIP or Wave project
    • If you have any questions, don't hesitate to start a discussion in #expensify-open-source

    Thanks!

  16. melvin-bot commented on Sep 17, 2026

    @melvin-bot

    @getusha Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!

  17. melvin-bot commented on Sep 21, 2026

    @melvin-bot

    @getusha Still overdue 6 days?! Let's take care of this!

  18. melvin-bot commented on Sep 23, 2026

    @melvin-bot

    @getusha Now this issue is 8 days overdue. Are you sure this should be a Daily? Feel free to change it!

  19. getusha commented on Sep 25, 2026

    @getusha
    Contributor

    The page changed we can close it.

  20. m-natarajan commented on Sep 25, 2026

    @m-natarajan

    The Create expense page layout changed and no more > to navigate to description and go back. we can now directly enter the description.
    Blocked from retesting this one.

    ScreenRecording_09-25-2026.20-06-17_1.MP4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

BugSomething is broken. Auto assigns a BugZero manager.DailyKSv2ExternalAdded to denote the issue can be worked on by a contributor

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions