[GH-ISSUE #7721] [Bug]: split transaction stays invisibly tied to original payee #80613

Open
opened 2026-05-19 04:26:48 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @zdimension on GitHub (May 5, 2026).
Original GitHub issue: https://github.com/actualbudget/actual/issues/7721

What happened?

When splitting a transaction, the parent transaction keeps having a payee even though semantically only the child ones have.

How can we reproduce the issue?

Say you have a transaction with payee Foo and amount $123. You split it and get:

Account      payee  amount
AccountName  Foo    $123
             Foo    $100
             Foo    $ 23

Note that here, the payee of the parent transaction is italicised in the UI since the UI actually displays a comma-separated list of the children's payees. At this point the parent transaction doesn't really have a payee anymore, semantically; its children do.

Next, you change the first child's payee:

Account      payee     amount
AccountName  Foo, Bar  $123
             Foo       $100
             Bar       $ 23

then the second's:

Account      payee  amount
AccountName  Bar    $123
             Bar    $100
             Bar    $ 23

Note that now the UI displays Bar as payee for the parent, since that's what the children have.

However, if you look at the payee list, "Foo" still exists and isn't marked as unused. If you search with a filter of "Foo", it displays our three transactions, but "Foo" appears nowhere on the screen. Indeed the parent transaction still has a payee of "Foo" but this isn't really relevant. Splitting the transaction should set the parent's payee to null.

Where are you hosting Actual?

None

What browsers are you seeing the problem on?

No response

Operating System

None

Originally created by @zdimension on GitHub (May 5, 2026). Original GitHub issue: https://github.com/actualbudget/actual/issues/7721 ### What happened? When splitting a transaction, the parent transaction keeps having a payee even though semantically only the child ones have. ### How can we reproduce the issue? Say you have a transaction with payee Foo and amount $123. You split it and get: ``` Account payee amount AccountName Foo $123 Foo $100 Foo $ 23 ``` Note that here, the payee of the parent transaction is italicised in the UI since the UI actually displays a comma-separated list of the children's payees. At this point the parent transaction doesn't really have a payee anymore, semantically; its children do. Next, you change the first child's payee: ``` Account payee amount AccountName Foo, Bar $123 Foo $100 Bar $ 23 ``` then the second's: ``` Account payee amount AccountName Bar $123 Bar $100 Bar $ 23 ``` Note that now the UI displays *Bar* as payee for the parent, since that's what the children have. However, if you look at the payee list, "Foo" still exists and isn't marked as unused. If you search with a filter of "Foo", it displays our three transactions, but "Foo" appears nowhere on the screen. Indeed the parent transaction still has a payee of "Foo" but this isn't really relevant. Splitting the transaction should set the parent's payee to `null`. ### Where are you hosting Actual? None ### What browsers are you seeing the problem on? _No response_ ### Operating System None
GiteaMirror added the split transactionsbughelp wantedgood first issue labels 2026-05-19 04:26:50 -05:00
Author
Owner

@jshaofa-ui commented on GitHub (May 10, 2026):

🔧 Solution Proposal

Root Cause

When splitting a transaction, the splitTransaction() function in packages/loot-core/src/shared/transactions.ts sets is_parent: true on the parent but does NOT clear its payee field. The codebase already clears category on parent transactions (in batchUpdateTransactions), but the same logic was never applied to payee.

Fix — Two-Pronged Approach

1. Clear payee at split time (packages/loot-core/src/shared/transactions.ts, splitTransaction() function)

Add payee: null to the parent transaction return object:

return {
  ...rest,
  is_parent: true,
  payee: null,  // ADD THIS LINE
  error: num(trans.amount) === 0 ? null : SplitTransactionError(0, trans),
  subtransactions: subtransactions.map(t => ({
    ...t,
    sort_order: t.sort_order || -1,
  })),
} satisfies TransactionEntity;

2. Clear payee during batch updates (packages/loot-core/src/server/transactions/index.ts, batchUpdateTransactions())

Add t.payee = null alongside the existing t.category = null in both is_parent checks:

if (t.is_parent || account?.offbudget === 1) {
  t.category = null;
  t.payee = null;  // ADD THIS LINE
}

Why This Works

  • Follows existing pattern: category is already cleared on parent transactions
  • Two locations ensure both new splits and existing split transactions are handled
  • payee is already nullable — no type changes needed
  • No UI changes required — purely a data layer fix
<!-- gh-comment-id:4414059471 --> @jshaofa-ui commented on GitHub (May 10, 2026): ## 🔧 Solution Proposal ### Root Cause When splitting a transaction, the `splitTransaction()` function in `packages/loot-core/src/shared/transactions.ts` sets `is_parent: true` on the parent but does NOT clear its `payee` field. The codebase already clears `category` on parent transactions (in `batchUpdateTransactions`), but the same logic was never applied to `payee`. ### Fix — Two-Pronged Approach **1. Clear payee at split time** (`packages/loot-core/src/shared/transactions.ts`, `splitTransaction()` function) Add `payee: null` to the parent transaction return object: ```typescript return { ...rest, is_parent: true, payee: null, // ADD THIS LINE error: num(trans.amount) === 0 ? null : SplitTransactionError(0, trans), subtransactions: subtransactions.map(t => ({ ...t, sort_order: t.sort_order || -1, })), } satisfies TransactionEntity; ``` **2. Clear payee during batch updates** (`packages/loot-core/src/server/transactions/index.ts`, `batchUpdateTransactions()`) Add `t.payee = null` alongside the existing `t.category = null` in both `is_parent` checks: ```typescript if (t.is_parent || account?.offbudget === 1) { t.category = null; t.payee = null; // ADD THIS LINE } ``` ### Why This Works - Follows existing pattern: `category` is already cleared on parent transactions - Two locations ensure both new splits and existing split transactions are handled - `payee` is already nullable — no type changes needed - No UI changes required — purely a data layer fix
Author
Owner

@zdimension commented on GitHub (May 10, 2026):

Your solution clears payees for offbudget transactions. This is unwanted.

<!-- gh-comment-id:4415263125 --> @zdimension commented on GitHub (May 10, 2026): Your solution clears payees for offbudget transactions. This is unwanted.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/actual#80613