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
Expense-In self dm, unable to delete the split expense. #94532
👋 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.
Please re-state the problem that we are trying to solve in this issue.
In a self DM, after splitting an existing expense (more → "Split the expense"), opening one of the resulting split expenses and trying to delete it (more → Delete) does nothing — the split can't be deleted.
What is the root cause of that problem?
Splitting an expense in a self DM is a not-yet-shipped feature that is hidden in production and only visible on staging/dev builds. The bug report confirms this — "Production behaviour: split option is not shown." The whole flow is gated on isProduction rather than a beta, and the delete path for the splits it produces is incompletely gated, so deleting a self-DM split routes into a "redistribute" path instead of an actual delete.
The entry point is hidden in prod via ReportSecondaryActionUtils.ts:148-151 (return !isProduction), and initSplitExpense early-returns in prod for self DM at SplitExpenses.ts:69-71. So on the staging build (V9.4.19-1) the option appears and creates split children that are unreported transactions on the self DM (moneyRequestReportID = UNREPORTED_REPORT_ID).
The delete then breaks because the self-DM/unreported short-circuit in the delete grouping is itself prod-only:
Delete path evidence
useDeleteTransactions.ts:199-203 — the isUnreportedSelfDMSplit short-circuit to the normal delete path runs only when isProduction:
constisUnreportedSelfDMSplit=transaction?.reportID===CONST.REPORT.UNREPORTED_REPORT_ID;if(isProduction&&isUnreportedSelfDMSplit){acc.nonSplitTransactions.push(item);// normal deleteMoneyRequest pathreturnacc;}
On the staging build (isProduction === false), the split instead falls into splitTransactionsByOriginalTransactionID and is handled by the split restore/redistribute path rather than deleteMoneyRequest, so the tapped split is not deleted.
Separately, the report-action context-menu Delete is hard-blocked for any SPLIT action at ReportUtils.ts:3232-3239 (// For now, users cannot delete split actions), which is why the option is missing from that surface too.
In short: this is staging-only behavior of an in-progress feature, not a production-facing regression.
What changes do you think we should make in order to solve the problem?
Because the feature is intentionally hidden in production, this likely should not block the deploy — confirm with the feature owner. To actually fix it for when self-DM split ships, make the delete path for unreported/self-DM split children environment-consistent: either drop the isProduction && qualifier on the isUnreportedSelfDMSplit short-circuit in useDeleteTransactions.ts:200 and the matching guard in getChildTransactions so unreported self-DM splits route to deleteMoneyRequest in all environments, or fully gate the self-DM split feature off until the delete flow is complete.
The right call (route-to-delete vs. fully gate off) depends on whether self-DM split is meant to ship soon — the feature owner should confirm the intended direction.
What alternative solutions did you explore?
Tracing the SPLIT context-menu action delete (canDeleteReportAction's SPLIT hard-block) — relevant to the context-menu surface, but the header Delete divergence above is the path the tester hit.
Confidence: High — this is determinable from code; the isProduction gating fully explains why it reproduces on staging but the option doesn't even appear in production.
Next Steps for Contributor+ team: To accept:@MelvinBot implement [this](https://github.com/Expensify/App/issues/94532) to create a draft PR. To refine:@MelvinBot <your feedback> To reject: Explain why you are rejecting Melvin's proposal.
@blimpich@stitesExpensify This issue was introduced by #91932, which added the isProduction guard. However, it only occurs in the staging and development environments because this feature is intentionally disabled in production.
I don't think we need to make any changes until #72125 is completed. Alternatively, if you'd prefer to hide the Delete split expense in self DM flow in staging and development until the feature is fully complete, please let me know.
Activity
applause-bot commentedon Jun 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/6879ff67c8a9c938bfc5178f88fd3b084b6ef3a42cc6bd4418fbe2e30cc6294e
melvin-bot commentedon Jun 25, 2026
Triggered auto assignment to @stitesExpensify (
DeployBlockerCash), see https://stackoverflowteams.com/c/expensify/questions/9980/ for more details.melvin-bot commentedon Jun 25, 2026
💬 A slack conversation has been started in #expensify-open-source
github-actions commentedon Jun 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:
MelvinBot commentedon Jun 25, 2026
Proposal
Please re-state the problem that we are trying to solve in this issue.
In a self DM, after splitting an existing expense (more → "Split the expense"), opening one of the resulting split expenses and trying to delete it (more → Delete) does nothing — the split can't be deleted.
What is the root cause of that problem?
Splitting an expense in a self DM is a not-yet-shipped feature that is hidden in production and only visible on staging/dev builds. The bug report confirms this — "Production behaviour: split option is not shown." The whole flow is gated on
isProductionrather than a beta, and the delete path for the splits it produces is incompletely gated, so deleting a self-DM split routes into a "redistribute" path instead of an actual delete.The entry point is hidden in prod via
ReportSecondaryActionUtils.ts:148-151(return !isProduction), andinitSplitExpenseearly-returns in prod for self DM atSplitExpenses.ts:69-71. So on the staging build (V9.4.19-1) the option appears and creates split children that are unreported transactions on the self DM (moneyRequestReportID = UNREPORTED_REPORT_ID).The delete then breaks because the self-DM/unreported short-circuit in the delete grouping is itself prod-only:
Delete path evidence
useDeleteTransactions.ts:199-203— theisUnreportedSelfDMSplitshort-circuit to the normal delete path runs only whenisProduction:On the staging build (
isProduction === false), the split instead falls intosplitTransactionsByOriginalTransactionIDand is handled by the split restore/redistribute path rather thandeleteMoneyRequest, so the tapped split is not deleted.getChildTransactions—TransactionUtils/index.ts:2787-2798similarly excludes unreported/self-DM children only in prod, so child counting diverges between environments.Separately, the report-action context-menu Delete is hard-blocked for any SPLIT action at
ReportUtils.ts:3232-3239(// For now, users cannot delete split actions), which is why the option is missing from that surface too.In short: this is staging-only behavior of an in-progress feature, not a production-facing regression.
What changes do you think we should make in order to solve the problem?
Because the feature is intentionally hidden in production, this likely should not block the deploy — confirm with the feature owner. To actually fix it for when self-DM split ships, make the delete path for unreported/self-DM split children environment-consistent: either drop the
isProduction &&qualifier on theisUnreportedSelfDMSplitshort-circuit inuseDeleteTransactions.ts:200and the matching guard ingetChildTransactionsso unreported self-DM splits route todeleteMoneyRequestin all environments, or fully gate the self-DM split feature off until the delete flow is complete.The right call (route-to-delete vs. fully gate off) depends on whether self-DM split is meant to ship soon — the feature owner should confirm the intended direction.
What alternative solutions did you explore?
Tracing the SPLIT context-menu action delete (
canDeleteReportAction's SPLIT hard-block) — relevant to the context-menu surface, but the header Delete divergence above is the path the tester hit.Confidence: High — this is determinable from code; the
isProductiongating fully explains why it reproduces on staging but the option doesn't even appear in production.Next Steps for Contributor+ team:
To accept:
@MelvinBot implement [this](https://github.com/Expensify/App/issues/94532)to create a draft PR.To refine:
@MelvinBot <your feedback>To reject: Explain why you are rejecting Melvin's proposal.
blimpich commentedon Jun 25, 2026
demoting https://expensify.slack.com/archives/C01GTK53T8Q/p1782406975105999?thread_ts=1782364177.294149&cid=C01GTK53T8Q
huult commentedon Jun 29, 2026
Checking...
huult commentedon Jun 29, 2026
Slack
huult commentedon Jun 30, 2026
@blimpich @stitesExpensify This issue was introduced by #91932, which added the
isProductionguard. However, it only occurs in the staging and development environments because this feature is intentionally disabled in production.I don't think we need to make any changes until #72125 is completed. Alternatively, if you'd prefer to hide the Delete split expense in self DM flow in staging and development until the feature is fully complete, please let me know.
melvin-bot commentedon Jun 30, 2026
@mananjadhav Huh... This is 4 days overdue. Who can take care of this?
stitesExpensify commentedon Jul 1, 2026
I think that it's fine to just leave as is. Thanks for investigating!