[Bug]: Entering an amount and then pressing Cleared toggle clears the amount #2586

Open
opened 2026-02-28 20:20:09 -06:00 by GiteaMirror · 2 comments
Owner

Originally created by @parapsychic on GitHub (Nov 2, 2025).

Verified issue does not already exist?

  • I have searched and found no existing issue

What happened?

I usually use the add transaction page to track my transactions. On mobile, when I enter an amount and then immediately click the cleared toggle, the amount vanishes.

https://github.com/user-attachments/assets/526ddb17-5f63-46e9-ba89-56dba385d829

How can we reproduce the issue?

On Chrome (Android)

  • Click on Add Transaction
  • Enter an amount
  • Without pressing back or letting the keyboard close, check the "Cleared" toggle.
  • The amount disappears

Where are you hosting Actual?

Docker

What browsers are you seeing the problem on?

Chrome

Operating System

Mobile Device

Originally created by @parapsychic on GitHub (Nov 2, 2025). ### Verified issue does not already exist? - [x] I have searched and found no existing issue ### What happened? I usually use the add transaction page to track my transactions. On mobile, when I enter an amount and then immediately click the cleared toggle, the amount vanishes. https://github.com/user-attachments/assets/526ddb17-5f63-46e9-ba89-56dba385d829 ### How can we reproduce the issue? On Chrome (Android) - Click on Add Transaction - Enter an amount - Without pressing back or letting the keyboard close, check the "Cleared" toggle. - The amount disappears ### Where are you hosting Actual? Docker ### What browsers are you seeing the problem on? Chrome ### Operating System Mobile Device
GiteaMirror added the user interfaceresponsivebug labels 2026-02-28 20:20:10 -06:00
Author
Owner

@parapsychic commented on GitHub (Nov 2, 2025):

I've checked this issue, and I think I know why this happens. It is like a race condition.

  • The amount is saved to state (persisted to local db too) on the onBlur event of the amount component. This event calls an onUpdateInner event, which in turn calls the onUpdate callback with the current state of the transaction (where amount = 0) passed into the callback.
  • The onUpdate callback has some asynchronous code, so while that happens, the onToggle function of the Cleared component calls the onUpdateInner. This also calls the onUpdate callback with a stale transaction state (where amount = 0).
  • The first callback returns from doing the async task and updates state to reflect the transaction (sets transaction.amount = X)
  • But the second callback from the cleared component overwrites the state again making transaction.amount = 0.

I've tried my best to fix this, but the code seems too complex imo for doing this simple task. But then again, I'm not really good at React, so 🤷. The issue 100% stems from passing the entire transaction state around and trusting the component to provide the transaction's state to update the transaction's state of the entire page.

Hopefully someone else can look into this and fix it, because now I have a whole bunch of zero transactions which I have no idea where it came from 🤣

@parapsychic commented on GitHub (Nov 2, 2025): I've checked this issue, and I think I know why this happens. It is like a race condition. - The amount is saved to state (persisted to local db too) on the `onBlur` event of the amount component. This event calls an `onUpdateInner` event, which in turn calls the `onUpdate` callback with the current state of the transaction (where amount = 0) passed into the callback. - The `onUpdate` callback has some asynchronous code, so while that happens, the `onToggle` function of the Cleared component calls the `onUpdateInner`. This also calls the `onUpdate` callback with a stale transaction state (where amount = 0). - The first callback returns from doing the async task and updates state to reflect the transaction (sets transaction.amount = X) - But the second callback from the cleared component overwrites the state again making transaction.amount = 0. I've tried my best to fix this, but the code seems too complex imo for doing this simple task. But then again, I'm not really good at React, so 🤷. The issue 100% stems from passing the entire transaction state around and trusting the component to provide the transaction's state to update the transaction's state of the entire page. Hopefully someone else can look into this and fix it, because now I have a whole bunch of zero transactions which I have no idea where it came from 🤣
Author
Owner

@CrimsonFlash commented on GitHub (Nov 21, 2025):

This also happens on the non-mobile browser and native macOS apps.

Solution I have found on desktop in the interim is to tab over before pressing the cleared button.

@CrimsonFlash commented on GitHub (Nov 21, 2025): This also happens on the non-mobile browser and native macOS apps. Solution I have found on desktop in the interim is to tab over before pressing the cleared button.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/actual#2586