diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx
index b5e658f87899..9e0a08860c0d 100644
--- a/src/components/MoneyReportHeader.tsx
+++ b/src/components/MoneyReportHeader.tsx
@@ -371,6 +371,7 @@ function MoneyReportHeader({
     const canTriggerAutomaticPDFDownload = useRef(false);
     const hasFinishedPDFDownload = reportPDFFilename && reportPDFFilename !== CONST.REPORT_DETAILS_MENU_ITEM.ERROR;
 
+    const [recentWaypoints] = useOnyx(ONYXKEYS.NVP_RECENT_WAYPOINTS, {canBeMissing: true});
     const [quickAction] = useOnyx(ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE, {canBeMissing: true});
     const [isSelfTourViewed = false] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {canBeMissing: true, selector: hasSeenTourSelector});
 
@@ -711,6 +712,7 @@ function MoneyReportHeader({
                     targetReport: activePolicyExpenseChat,
                     betas,
                     personalDetails,
+                    recentWaypoints,
                 });
             }
         },
@@ -727,6 +729,7 @@ function MoneyReportHeader({
             isSelfTourViewed,
             betas,
             personalDetails,
+            recentWaypoints,
         ],
     );
 
diff --git a/src/components/MoneyRequestHeader.tsx b/src/components/MoneyRequestHeader.tsx
index fc20bc095429..530cae40915b 100644
--- a/src/components/MoneyRequestHeader.tsx
+++ b/src/components/MoneyRequestHeader.tsx
@@ -161,6 +161,7 @@ function MoneyRequestHeader({report, parentReportAction, policy, onBackButtonPre
     const isASAPSubmitBetaEnabled = isBetaEnabled(CONST.BETAS.ASAP_SUBMIT);
     const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED, {canBeMissing: true});
     const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID, {canBeMissing: true});
+    const [recentWaypoints] = useOnyx(ONYXKEYS.NVP_RECENT_WAYPOINTS, {canBeMissing: true});
 
     const {isDelegateAccessRestricted} = useDelegateNoAccessState();
     const {showDelegateNoAccessModal} = useDelegateNoAccessActions();
@@ -217,6 +218,7 @@ function MoneyRequestHeader({report, parentReportAction, policy, onBackButtonPre
                     targetReport: activePolicyExpenseChat,
                     betas,
                     personalDetails,
+                    recentWaypoints,
                 });
             }
         },
@@ -233,6 +235,7 @@ function MoneyRequestHeader({report, parentReportAction, policy, onBackButtonPre
             isSelfTourViewed,
             betas,
             personalDetails,
+            recentWaypoints,
         ],
     );
 
diff --git a/src/libs/actions/IOU/Duplicate.ts b/src/libs/actions/IOU/Duplicate.ts
index da50ad37aa49..f936826c6bd6 100644
--- a/src/libs/actions/IOU/Duplicate.ts
+++ b/src/libs/actions/IOU/Duplicate.ts
@@ -35,7 +35,6 @@ import {
     getCurrentUserEmail,
     getMoneyRequestParticipantsFromReport,
     getPolicyTags,
-    getRecentWaypoints,
     getUserAccountID,
     requestMoney,
     submitPerDiemExpense,
@@ -505,6 +504,7 @@ type DuplicateExpenseTransactionParams = {
     targetReport?: OnyxTypes.Report;
     betas: OnyxEntry<OnyxTypes.Beta[]>;
     personalDetails: OnyxEntry<OnyxTypes.PersonalDetailsList>;
+    recentWaypoints: OnyxEntry<OnyxTypes.RecentWaypoint[]>;
 };
 
 function duplicateExpenseTransaction({
@@ -523,6 +523,7 @@ function duplicateExpenseTransaction({
     targetReport,
     betas,
     personalDetails,
+    recentWaypoints,
 }: DuplicateExpenseTransactionParams) {
     if (!transaction) {
         return;
@@ -530,7 +531,6 @@ function duplicateExpenseTransaction({
 
     const userAccountID = getUserAccountID();
     const currentUserEmail = getCurrentUserEmail();
-    const recentWaypoints = getRecentWaypoints();
 
     const participants = getMoneyRequestParticipantsFromReport(targetReport, userAccountID);
     const transactionDetails = getTransactionDetails(transaction);
diff --git a/tests/actions/IOUTest/DuplicateTest.ts b/tests/actions/IOUTest/DuplicateTest.ts
index 828a0b9a35d5..4d32df4bb0ad 100644
--- a/tests/actions/IOUTest/DuplicateTest.ts
+++ b/tests/actions/IOUTest/DuplicateTest.ts
@@ -16,7 +16,7 @@ import IntlStore from '@src/languages/IntlStore';
 import OnyxUpdateManager from '@src/libs/actions/OnyxUpdateManager';
 import * as API from '@src/libs/API';
 import ONYXKEYS from '@src/ONYXKEYS';
-import type {OriginalMessageIOU, Report, ReportActions} from '@src/types/onyx';
+import type {OriginalMessageIOU, RecentWaypoint, Report, ReportActions} from '@src/types/onyx';
 import type ReportAction from '@src/types/onyx/ReportAction';
 import type {ReportActionsCollectionDataSet} from '@src/types/onyx/ReportAction';
 import type Transaction from '@src/types/onyx/Transaction';
@@ -890,6 +890,7 @@ describe('actions/Duplicate', () => {
 
     describe('duplicateExpenseTransaction', () => {
         let writeSpy: jest.SpyInstance;
+        let recentWaypoints: RecentWaypoint[] = [];
 
         const mockOptimisticChatReportID = '789';
         const mockOptimisticIOUReportID = '987';
@@ -900,7 +901,7 @@ describe('actions/Duplicate', () => {
         const policyExpenseChat = createRandomReport(1, CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT);
         const fakePolicyCategories = createRandomPolicyCategories(3);
 
-        beforeEach(() => {
+        beforeEach(async () => {
             jest.clearAllMocks();
             global.fetch = getGlobalFetchMock();
             // eslint-disable-next-line rulesdir/no-multiple-api-calls
@@ -917,6 +918,7 @@ describe('actions/Duplicate', () => {
                 }
                 return Promise.resolve();
             });
+            recentWaypoints = (await getOnyxValue(ONYXKEYS.NVP_RECENT_WAYPOINTS)) ?? [];
             return Onyx.clear();
         });
 
@@ -952,6 +954,7 @@ describe('actions/Duplicate', () => {
                 targetReport: policyExpenseChat,
                 betas: [CONST.BETAS.ALL],
                 personalDetails: {},
+                recentWaypoints,
             });
 
             await waitForBatchedUpdates();
@@ -1011,6 +1014,7 @@ describe('actions/Duplicate', () => {
                 targetReport: policyExpenseChat,
                 betas: [CONST.BETAS.ALL],
                 personalDetails: {},
+                recentWaypoints,
             });
 
             await waitForBatchedUpdates();
@@ -1070,6 +1074,7 @@ describe('actions/Duplicate', () => {
                 targetReport: policyExpenseChat,
                 betas: [CONST.BETAS.ALL],
                 personalDetails: {},
+                recentWaypoints,
             });
 
             await waitForBatchedUpdates();
@@ -1146,6 +1151,7 @@ describe('actions/Duplicate', () => {
                 targetReport: policyExpenseChat,
                 betas: [CONST.BETAS.ALL],
                 personalDetails: {},
+                recentWaypoints,
             });
 
             await waitForBatchedUpdates();
@@ -1161,6 +1167,118 @@ describe('actions/Duplicate', () => {
             const apiParams = requestMoneyCall?.[1] as Record<string, unknown>;
             expect(apiParams?.transactionThreadReportID).not.toBe(existingLinkedReportActionChildReportID);
         });
+
+        it('should call trackExpense API when targetPolicy is not provided', async () => {
+            const {waypoints, ...restOfComment} = mockTransaction.comment ?? {};
+            const mockCashExpenseTransaction = {
+                ...mockTransaction,
+                amount: mockTransaction.amount * -1,
+                comment: {
+                    ...restOfComment,
+                },
+            };
+
+            await Onyx.clear();
+
+            // When duplicating the transaction without targetPolicy
+            duplicateExpenseTransaction({
+                transaction: mockCashExpenseTransaction,
+                optimisticChatReportID: mockOptimisticChatReportID,
+                optimisticIOUReportID: mockOptimisticIOUReportID,
+                isASAPSubmitBetaEnabled: mockIsASAPSubmitBetaEnabled,
+                introSelected: undefined,
+                activePolicyID: undefined,
+                quickAction: undefined,
+                policyRecentlyUsedCurrencies: [],
+                isSelfTourViewed: false,
+                customUnitPolicyID: '',
+                targetPolicy: undefined,
+                targetPolicyCategories: undefined,
+                targetReport: undefined,
+                betas: [CONST.BETAS.ALL],
+                personalDetails: {},
+                recentWaypoints,
+            });
+
+            await waitForBatchedUpdates();
+
+            // Then the API should have been called with TRACK_EXPENSE instead of REQUEST_MONEY
+            const trackExpenseCall = writeSpy.mock.calls.find((call: [string, Record<string, unknown>]) => call[0] === WRITE_COMMANDS.TRACK_EXPENSE);
+            const requestMoneyCall = writeSpy.mock.calls.find((call: [string, Record<string, unknown>]) => call[0] === WRITE_COMMANDS.REQUEST_MONEY);
+
+            expect(trackExpenseCall).toBeDefined();
+            expect(requestMoneyCall).toBeUndefined();
+
+            // Then a transaction should be created successfully
+            let duplicatedTransaction: OnyxEntry<Transaction>;
+
+            await getOnyxData({
+                key: ONYXKEYS.COLLECTION.TRANSACTION,
+                waitForCollectionCallback: true,
+                callback: (allTransactions) => {
+                    duplicatedTransaction = Object.values(allTransactions ?? {}).find((t) => !!t);
+                },
+            });
+
+            expect(duplicatedTransaction).toBeDefined();
+            expect(duplicatedTransaction?.transactionID).not.toBe(mockCashExpenseTransaction.transactionID);
+        });
+
+        it('should preserve all transaction fields when duplicating Cash expense', async () => {
+            // Given a transaction with all fields populated using mockTransaction values
+            const {waypoints, ...restOfComment} = mockTransaction.comment ?? {};
+            const mockCashExpense: Transaction = {
+                ...mockTransaction,
+                amount: mockTransaction.amount * -1,
+                comment: {
+                    ...restOfComment,
+                },
+            };
+
+            await Onyx.clear();
+
+            // When duplicating the transaction
+            duplicateExpenseTransaction({
+                transaction: mockCashExpense,
+                optimisticChatReportID: mockOptimisticChatReportID,
+                optimisticIOUReportID: mockOptimisticIOUReportID,
+                isASAPSubmitBetaEnabled: mockIsASAPSubmitBetaEnabled,
+                introSelected: undefined,
+                activePolicyID: undefined,
+                quickAction: undefined,
+                policyRecentlyUsedCurrencies: [],
+                isSelfTourViewed: false,
+                customUnitPolicyID: '',
+                targetPolicy: mockPolicy,
+                targetPolicyCategories: fakePolicyCategories,
+                targetReport: policyExpenseChat,
+                betas: [CONST.BETAS.ALL],
+                personalDetails: {},
+                recentWaypoints,
+            });
+
+            await waitForBatchedUpdates();
+
+            // The duplicated transaction should have all fields preserved
+            let duplicatedTransaction: OnyxEntry<Transaction>;
+
+            await getOnyxData({
+                key: ONYXKEYS.COLLECTION.TRANSACTION,
+                waitForCollectionCallback: true,
+                callback: (allTransactions) => {
+                    duplicatedTransaction = Object.values(allTransactions ?? {}).find((t) => !!t);
+                },
+            });
+
+            expect(duplicatedTransaction).toBeDefined();
+            expect(duplicatedTransaction?.transactionID).not.toBe(mockCashExpense.transactionID);
+            expect(duplicatedTransaction?.category).toBe(mockTransaction.category);
+            expect(duplicatedTransaction?.tag).toBe(mockTransaction.tag);
+            expect(duplicatedTransaction?.billable).toBe(mockTransaction.billable);
+            expect(duplicatedTransaction?.reimbursable).toBe(mockTransaction.reimbursable);
+            expect(duplicatedTransaction?.currency).toBe(mockTransaction.currency);
+            expect(Math.abs(duplicatedTransaction?.amount ?? 0)).toBe(Math.abs(mockTransaction.amount));
+        });
     });
 
     describe('resolveDuplicate', () => {
