diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-1-chromium-linux.png b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-1-chromium-linux.png
index 75ecd7a13fb384b69ba28fd7d7d9005bb33dede2..0520ca7e91b5d90eb5b823ac02c0c6a30c26c631 100644
Binary files a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-1-chromium-linux.png and b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-1-chromium-linux.png differ
diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-2-chromium-linux.png b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-2-chromium-linux.png
index 7ac8627924a87e0f4feb8dd51f08a036e3af33eb..89beb5a8f561a406377291e822922b891f1bc593 100644
Binary files a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-2-chromium-linux.png and b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-2-chromium-linux.png differ
diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-3-chromium-linux.png b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-3-chromium-linux.png
index ce38feb390e46032673d4d0513ee7bfdca025c65..c761f2225e748e7d1651eca8ffd21a49fdbfad69 100644
Binary files a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-3-chromium-linux.png and b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-creates-a-transaction-via-footer-button-3-chromium-linux.png differ
diff --git a/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-1-chromium-linux.png b/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-1-chromium-linux.png
index be2af3a31ee60ed3fe18a39c2429d2426becdb91..3cb6f9c634549ef7b3bdb91030a6eb669d885aef 100644
Binary files a/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-1-chromium-linux.png and b/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-1-chromium-linux.png differ
diff --git a/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-2-chromium-linux.png b/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-2-chromium-linux.png
index 4722fad3d167f4015a48706b75a63062ddeb0585..e2988c222b7199a9c462dd7405d531760834030e 100644
Binary files a/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-2-chromium-linux.png and b/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-2-chromium-linux.png differ
diff --git a/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-3-chromium-linux.png b/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-3-chromium-linux.png
index 0f2889138a096e405286cd418bc585aceabfa1cb..717ce7b1abd35c8ecce65631d76106fc959eb0cf 100644
Binary files a/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-3-chromium-linux.png and b/packages/desktop-client/e2e/rules.test.js-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-3-chromium-linux.png differ
diff --git a/packages/desktop-client/src/components/Modals.tsx b/packages/desktop-client/src/components/Modals.tsx
index 643ea94784facd7d919aae559fc09e58f0c6107b..d42fe09eb87a8a970f5d2cd6abe1321dc83212c0 100644
--- a/packages/desktop-client/src/components/Modals.tsx
+++ b/packages/desktop-client/src/components/Modals.tsx
@@ -21,6 +21,7 @@ import { CategoryGroupMenuModal } from './modals/CategoryGroupMenuModal';
 import { CategoryMenuModal } from './modals/CategoryMenuModal';
 import { CloseAccountModal } from './modals/CloseAccountModal';
 import { ConfirmCategoryDelete } from './modals/ConfirmCategoryDelete';
+import { ConfirmTransactionDelete } from './modals/ConfirmTransactionDelete';
 import { ConfirmTransactionEdit } from './modals/ConfirmTransactionEdit';
 import { ConfirmUnlinkAccount } from './modals/ConfirmUnlinkAccount';
 import { CoverModal } from './modals/CoverModal';
@@ -177,6 +178,15 @@ export function Modals() {
             />
           );
 
+        case 'confirm-transaction-delete':
+          return (
+            <ConfirmTransactionDelete
+              key={name}
+              modalProps={modalProps}
+              onConfirm={options.onConfirm}
+            />
+          );
+
         case 'load-backup':
           return (
             <LoadBackup
diff --git a/packages/desktop-client/src/components/Notifications.tsx b/packages/desktop-client/src/components/Notifications.tsx
index 6acb901fc2aa431723b83607c26eece63121635a..bb2a45be2e0814f9a885039ef53a4aba5155fdac 100644
--- a/packages/desktop-client/src/components/Notifications.tsx
+++ b/packages/desktop-client/src/components/Notifications.tsx
@@ -95,6 +95,7 @@ function Notification({
     sticky,
     internal,
     button,
+    timeout,
   } = notification;
 
   const [loading, setLoading] = useState(false);
@@ -106,7 +107,7 @@ function Notification({
     }
 
     if (!sticky) {
-      setTimeout(onRemove, 6500);
+      setTimeout(onRemove, timeout || 6500);
     }
   }, []);
 
diff --git a/packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx b/packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx
index 821e54de6d6de2616da4cdd75af75586286aea42..033e0045d910b6f00a4fb053b4c41c22512e8d57 100644
--- a/packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx
+++ b/packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx
@@ -50,7 +50,7 @@ import {
   useSingleActiveEditForm,
 } from '../../../hooks/useSingleActiveEditForm';
 import { SvgSplit } from '../../../icons/v0';
-import { SvgAdd, SvgTrash } from '../../../icons/v1';
+import { SvgAdd, SvgPiggyBank, SvgTrash } from '../../../icons/v1';
 import { SvgPencilWriteAlternate } from '../../../icons/v2';
 import { styles, theme } from '../../../style';
 import { Button } from '../../common/Button';
@@ -170,6 +170,7 @@ function Footer({
   onAddSplit,
   onEmptySplitFound,
   editingField,
+  onEditField,
 }) {
   const [transaction, ...childTransactions] = transactions;
   const onClickRemainingSplit = () => {
@@ -200,7 +201,7 @@ function Footer({
       {transaction.error?.type === 'SplitTransactionError' ? (
         <Button
           type="primary"
-          style={{ height: 40 }}
+          style={{ height: styles.mobileMinHeight }}
           disabled={editingField}
           onClick={onClickRemainingSplit}
           onPointerDown={e => e.preventDefault()}
@@ -220,10 +221,28 @@ function Footer({
             )}
           </Text>
         </Button>
+      ) : !transaction.account ? (
+        <Button
+          type="primary"
+          style={{ height: styles.mobileMinHeight }}
+          disabled={editingField}
+          onClick={() => onEditField(transaction.id, 'account')}
+          onPointerDown={e => e.preventDefault()}
+        >
+          <SvgPiggyBank width={17} height={17} />
+          <Text
+            style={{
+              ...styles.text,
+              marginLeft: 6,
+            }}
+          >
+            Select account
+          </Text>
+        </Button>
       ) : adding ? (
         <Button
           type="primary"
-          style={{ height: 40 }}
+          style={{ height: styles.mobileMinHeight }}
           disabled={editingField}
           onClick={onAdd}
           onPointerDown={e => e.preventDefault()}
@@ -241,7 +260,7 @@ function Footer({
       ) : (
         <Button
           type="primary"
-          style={{ height: 40 }}
+          style={{ height: styles.mobileMinHeight }}
           disabled={editingField}
           onClick={onSave}
           onPointerDown={e => e.preventDefault()}
@@ -270,8 +289,8 @@ const ChildTransactionEdit = forwardRef(
       getPrettyPayee,
       isOffBudget,
       isBudgetTransfer,
-      onClick,
-      onEdit,
+      onEditField,
+      onUpdate,
       onDelete,
     },
     ref,
@@ -302,7 +321,7 @@ const ChildTransactionEdit = forwardRef(
                 editingField !== getFieldName(transaction.id, 'payee')
               }
               value={getPrettyPayee(transaction)}
-              onClick={() => onClick(transaction.id, 'payee')}
+              onClick={() => onEditField(transaction.id, 'payee')}
               data-testid={`payee-field-${transaction.id}`}
             />
           </View>
@@ -328,7 +347,7 @@ const ChildTransactionEdit = forwardRef(
               onUpdate={value => {
                 const amount = integerToAmount(value);
                 if (transaction.amount !== amount) {
-                  onEdit(transaction, 'amount', amount);
+                  onUpdate(transaction, 'amount', amount);
                 } else {
                   onClearActiveEdit();
                 }
@@ -355,7 +374,7 @@ const ChildTransactionEdit = forwardRef(
               isOffBudget ||
               isBudgetTransfer(transaction)
             }
-            onClick={() => onClick(transaction.id, 'category')}
+            onClick={() => onEditField(transaction.id, 'category')}
             data-testid={`category-field-${transaction.id}`}
           />
         </View>
@@ -371,7 +390,7 @@ const ChildTransactionEdit = forwardRef(
             onFocus={() =>
               onRequestActiveEdit(getFieldName(transaction.id, 'notes'))
             }
-            onUpdate={value => onEdit(transaction, 'notes', value)}
+            onUpdate={value => onUpdate(transaction, 'notes', value)}
           />
         </View>
 
@@ -489,7 +508,7 @@ const TransactionEditInner = memo(function TransactionEditInner({
 
   const onTotalAmountUpdate = value => {
     if (transaction.amount !== value) {
-      onEdit(transaction, 'amount', value.toString());
+      onUpdate(transaction, 'amount', value.toString());
     } else {
       onClearActiveEdit();
     }
@@ -502,12 +521,6 @@ const TransactionEditInner = memo(function TransactionEditInner({
       const { account: accountId } = unserializedTransaction;
       const account = accountsById[accountId];
 
-      if (unserializedTransactions.find(t => t.account == null)) {
-        // Ignore transactions if any of them don't have an account
-        // TODO: Should we display validation error?
-        return;
-      }
-
       let transactionsToSave = unserializedTransactions;
       if (adding) {
         transactionsToSave = realizeTempTransactions(unserializedTransactions);
@@ -537,13 +550,13 @@ const TransactionEditInner = memo(function TransactionEditInner({
     onSave();
   };
 
-  const onEdit = async (serializedTransaction, name, value) => {
+  const onUpdate = async (serializedTransaction, name, value) => {
     const newTransaction = { ...serializedTransaction, [name]: value };
-    await props.onEdit(newTransaction);
+    await props.onUpdate(newTransaction);
     onClearActiveEdit();
   };
 
-  const onClick = (transactionId, name) => {
+  const onEditField = (transactionId, name) => {
     onRequestActiveEdit?.(getFieldName(transaction.id, name), () => {
       const transactionToEdit = transactions.find(t => t.id === transactionId);
       const unserializedTransaction = unserializedTransactions.find(
@@ -556,7 +569,7 @@ const TransactionEditInner = memo(function TransactionEditInner({
               categoryGroups,
               month: monthUtils.monthFromDate(unserializedTransaction.date),
               onSelect: categoryId => {
-                onEdit(transactionToEdit, name, categoryId);
+                onUpdate(transactionToEdit, name, categoryId);
               },
               onClose: () => {
                 onClearActiveEdit();
@@ -568,7 +581,7 @@ const TransactionEditInner = memo(function TransactionEditInner({
           dispatch(
             pushModal('account-autocomplete', {
               onSelect: accountId => {
-                onEdit(transactionToEdit, name, accountId);
+                onUpdate(transactionToEdit, name, accountId);
               },
               onClose: () => {
                 onClearActiveEdit();
@@ -580,7 +593,7 @@ const TransactionEditInner = memo(function TransactionEditInner({
           dispatch(
             pushModal('payee-autocomplete', {
               onSelect: payeeId => {
-                onEdit(transactionToEdit, name, payeeId);
+                onUpdate(transactionToEdit, name, payeeId);
               },
               onClose: () => {
                 onClearActiveEdit();
@@ -594,7 +607,7 @@ const TransactionEditInner = memo(function TransactionEditInner({
               name,
               month: monthUtils.monthFromDate(unserializedTransaction.date),
               onSubmit: (name, value) => {
-                onEdit(transactionToEdit, name, value);
+                onUpdate(transactionToEdit, name, value);
               },
               onClose: () => {
                 onClearActiveEdit();
@@ -610,20 +623,26 @@ const TransactionEditInner = memo(function TransactionEditInner({
     const [unserializedTransaction] = unserializedTransactions;
 
     const onConfirmDelete = () => {
-      props.onDelete(id);
-
-      if (unserializedTransaction.id !== id) {
-        // Only a child transaction was deleted.
-        onClearActiveEdit();
-        return;
-      }
+      dispatch(
+        pushModal('confirm-transaction-delete', {
+          onConfirm: () => {
+            props.onDelete(id);
+
+            if (unserializedTransaction.id !== id) {
+              // Only a child transaction was deleted.
+              onClearActiveEdit();
+              return;
+            }
 
-      const { account: accountId } = unserializedTransaction;
-      if (accountId) {
-        navigate(`/accounts/${accountId}`, { replace: true });
-      } else {
-        navigate(-1);
-      }
+            const { account: accountId } = unserializedTransaction;
+            if (accountId) {
+              navigate(`/accounts/${accountId}`, { replace: true });
+            } else {
+              navigate(-1);
+            }
+          },
+        }),
+      );
     };
 
     if (unserializedTransaction.reconciled) {
@@ -710,6 +729,7 @@ const TransactionEditInner = memo(function TransactionEditInner({
           onAddSplit={onAddSplit}
           onEmptySplitFound={onEmptySplitFound}
           editingField={editingField}
+          onEditField={onEditField}
         />
       }
       padding={0}
@@ -746,7 +766,7 @@ const TransactionEditInner = memo(function TransactionEditInner({
               editingField !== getFieldName(transaction.id, 'payee')
             }
             value={getPrettyPayee(transaction)}
-            onClick={() => onClick(transaction.id, 'payee')}
+            onClick={() => onEditField(transaction.id, 'payee')}
             data-testid="payee-field"
           />
         </View>
@@ -769,7 +789,7 @@ const TransactionEditInner = memo(function TransactionEditInner({
                 isOffBudget ||
                 isBudgetTransfer(transaction)
               }
-              onClick={() => onClick(transaction.id, 'category')}
+              onClick={() => onEditField(transaction.id, 'category')}
               data-testid="category-field"
             />
           </View>
@@ -790,8 +810,8 @@ const TransactionEditInner = memo(function TransactionEditInner({
             getCategory={getCategory}
             getPrettyPayee={getPrettyPayee}
             isBudgetTransfer={isBudgetTransfer}
-            onEdit={onEdit}
-            onClick={onClick}
+            onUpdate={onUpdate}
+            onEditField={onEditField}
             onDelete={onDelete}
           />
         ))}
@@ -838,7 +858,7 @@ const TransactionEditInner = memo(function TransactionEditInner({
                 editingField !== getFieldName(transaction.id, 'account'))
             }
             value={account?.name}
-            onClick={() => onClick(transaction.id, 'account')}
+            onClick={() => onEditField(transaction.id, 'account')}
             data-testid="account-field"
           />
         </View>
@@ -859,7 +879,7 @@ const TransactionEditInner = memo(function TransactionEditInner({
                 onRequestActiveEdit(getFieldName(transaction.id, 'date'))
               }
               onUpdate={value =>
-                onEdit(
+                onUpdate(
                   transaction,
                   'date',
                   formatDate(parseISO(value), dateFormat),
@@ -886,7 +906,7 @@ const TransactionEditInner = memo(function TransactionEditInner({
               <BooleanField
                 disabled={editingField}
                 checked={transaction.cleared}
-                onUpdate={checked => onEdit(transaction, 'cleared', checked)}
+                onUpdate={checked => onUpdate(transaction, 'cleared', checked)}
                 style={{
                   margin: 'auto',
                   width: 22,
@@ -908,7 +928,7 @@ const TransactionEditInner = memo(function TransactionEditInner({
             onFocus={() => {
               onRequestActiveEdit(getFieldName(transaction.id, 'notes'));
             }}
-            onUpdate={value => onEdit(transaction, 'notes', value)}
+            onUpdate={value => onUpdate(transaction, 'notes', value)}
           />
         </View>
 
@@ -1030,7 +1050,7 @@ function TransactionEditUnconnected({
     return null;
   }
 
-  const onEdit = async serializedTransaction => {
+  const onUpdate = async serializedTransaction => {
     const transaction = deserializeTransaction(
       serializedTransaction,
       null,
@@ -1135,7 +1155,7 @@ function TransactionEditUnconnected({
         payees={payees}
         navigate={navigate}
         dateFormat={dateFormat}
-        onEdit={onEdit}
+        onUpdate={onUpdate}
         onSave={onSave}
         onDelete={onDelete}
         onSplit={onSplit}
diff --git a/packages/desktop-client/src/components/modals/ConfirmTransactionDelete.tsx b/packages/desktop-client/src/components/modals/ConfirmTransactionDelete.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..6d465b8e0e288de98be1bb86c5f61bcdf67f1523
--- /dev/null
+++ b/packages/desktop-client/src/components/modals/ConfirmTransactionDelete.tsx
@@ -0,0 +1,60 @@
+import React from 'react';
+
+import { useResponsive } from '../../ResponsiveProvider';
+import { styles } from '../../style';
+import { Button } from '../common/Button';
+import { Modal } from '../common/Modal';
+import { Paragraph } from '../common/Paragraph';
+import { View } from '../common/View';
+import { type CommonModalProps } from '../Modals';
+
+type ConfirmTransactionDeleteProps = {
+  modalProps: CommonModalProps;
+  onConfirm: () => void;
+};
+
+export function ConfirmTransactionDelete({
+  modalProps,
+  onConfirm,
+}: ConfirmTransactionDeleteProps) {
+  const { isNarrowWidth } = useResponsive();
+  const narrowButtonStyle = isNarrowWidth
+    ? {
+        height: styles.mobileMinHeight,
+      }
+    : {};
+
+  return (
+    <Modal title="Confirm Delete" {...modalProps}>
+      <View style={{ lineHeight: 1.5 }}>
+        <Paragraph>Are you sure you want to delete the transaction?</Paragraph>
+        <View
+          style={{
+            flexDirection: 'row',
+            justifyContent: 'flex-end',
+          }}
+        >
+          <Button
+            style={{
+              marginRight: 10,
+              ...narrowButtonStyle,
+            }}
+            onClick={modalProps.onClose}
+          >
+            Cancel
+          </Button>
+          <Button
+            type="primary"
+            style={narrowButtonStyle}
+            onClick={() => {
+              onConfirm();
+              modalProps.onClose();
+            }}
+          >
+            Delete
+          </Button>
+        </View>
+      </View>
+    </Modal>
+  );
+}
diff --git a/packages/loot-core/src/client/state-types/modals.d.ts b/packages/loot-core/src/client/state-types/modals.d.ts
index 4f0b190dcabdae9de61f040bb87d9304eb490ba7..4e607993c8c6a0ef31c1bff2170018248ff26120 100644
--- a/packages/loot-core/src/client/state-types/modals.d.ts
+++ b/packages/loot-core/src/client/state-types/modals.d.ts
@@ -247,6 +247,13 @@ type FinanceModals = {
     onEditNotes: (month: string) => void;
   };
   'budget-list';
+  'confirm-transaction-edit': {
+    onConfirm: () => void;
+    confirmReason: string;
+  };
+  'confirm-transaction-delete': {
+    onConfirm: () => void;
+  };
 };
 
 export type PushModalAction = {
diff --git a/packages/loot-core/src/client/state-types/notifications.d.ts b/packages/loot-core/src/client/state-types/notifications.d.ts
index 236f714059e26bb2e6f625a0dcff9388766e672b..551916e9f4249c852107290c1913899383e53aec 100644
--- a/packages/loot-core/src/client/state-types/notifications.d.ts
+++ b/packages/loot-core/src/client/state-types/notifications.d.ts
@@ -15,7 +15,7 @@ export type Notification = {
   };
   messageActions?: Record<string, () => void>;
   onClose?: () => void;
-  internal?: unknown;
+  internal?: string;
 };
 type NotificationWithId = Notification & { id: string };
 
diff --git a/upcoming-release-notes/2753.md b/upcoming-release-notes/2753.md
new file mode 100644
index 0000000000000000000000000000000000000000..9af1b9480e93beb4747893ced198ced142760b4a
--- /dev/null
+++ b/upcoming-release-notes/2753.md
@@ -0,0 +1,6 @@
+---
+category: Enhancements
+authors: [joel-jeremy]
+---
+
+Require account in mobile transaction entry + confirm transaction delete.