diff --git a/src/CONST.ts b/src/CONST.ts
index 9dd67b77e218..f6cc32c5259e 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -5362,6 +5362,10 @@ const CONST = {
         DATE: 'date',
         LIST: 'dropdown',
     },
+
+    NAVIGATION_ACTIONS: {
+        RESET: 'RESET',
+    },
 } as const;
 
 type Country = keyof typeof CONST.ALL_COUNTRIES;
diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts
index ee31b52750f4..d2325e368c3b 100755
--- a/src/ONYXKEYS.ts
+++ b/src/ONYXKEYS.ts
@@ -320,6 +320,9 @@ const ONYXKEYS = {
     /** Onboarding Purpose selected by the user during Onboarding flow */
     ONBOARDING_PURPOSE_SELECTED: 'onboardingPurposeSelected',
 
+    /** Onboarding error message to be displayed to the user */
+    ONBOARDING_ERROR_MESSAGE: 'onboardingErrorMessage',
+
     /** Onboarding policyID selected by the user during Onboarding flow */
     ONBOARDING_POLICY_ID: 'onboardingPolicyID',
 
@@ -812,6 +815,7 @@ type OnyxValuesMapping = {
     [ONYXKEYS.MAX_CANVAS_HEIGHT]: number;
     [ONYXKEYS.MAX_CANVAS_WIDTH]: number;
     [ONYXKEYS.ONBOARDING_PURPOSE_SELECTED]: string;
+    [ONYXKEYS.ONBOARDING_ERROR_MESSAGE]: string;
     [ONYXKEYS.ONBOARDING_POLICY_ID]: string;
     [ONYXKEYS.ONBOARDING_ADMINS_CHAT_REPORT_ID]: string;
     [ONYXKEYS.IS_SEARCHING_FOR_REPORTS]: boolean;
diff --git a/src/languages/en.ts b/src/languages/en.ts
index a8281e609305..f917ea66b275 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -1476,6 +1476,7 @@ export default {
             title: 'What do you want to do today?',
             errorSelection: 'Please make a selection to continue.',
             errorContinue: 'Please press continue to get set up.',
+            errorBackButton: 'Please finish the setup questions to start using the app.',
             [CONST.ONBOARDING_CHOICES.EMPLOYER]: 'Get paid back by my employer',
             [CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: "Manage my team's expenses",
             [CONST.ONBOARDING_CHOICES.PERSONAL_SPEND]: 'Track and budget expenses',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index bbbbbfc79bac..37ac0808cfdf 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -1487,6 +1487,7 @@ export default {
             title: '¿Qué quieres hacer hoy?',
             errorSelection: 'Por favor selecciona una opción para continuar.',
             errorContinue: 'Por favor, haz click en continuar para configurar tu cuenta.',
+            errorBackButton: 'Por favor, finaliza las preguntas de configuración para empezar a utilizar la aplicación.',
             [CONST.ONBOARDING_CHOICES.EMPLOYER]: 'Cobrar de mi empresa',
             [CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: 'Gestionar los gastos de mi equipo',
             [CONST.ONBOARDING_CHOICES.PERSONAL_SPEND]: 'Controlar y presupuestar gastos',
diff --git a/src/libs/Navigation/AppNavigator/Navigators/OnboardingModalNavigator.tsx b/src/libs/Navigation/AppNavigator/Navigators/OnboardingModalNavigator.tsx
index 29a2205b2e37..61adcd77da76 100644
--- a/src/libs/Navigation/AppNavigator/Navigators/OnboardingModalNavigator.tsx
+++ b/src/libs/Navigation/AppNavigator/Navigators/OnboardingModalNavigator.tsx
@@ -4,9 +4,11 @@ import {View} from 'react-native';
 import {useOnyx} from 'react-native-onyx';
 import NoDropZone from '@components/DragAndDrop/NoDropZone';
 import FocusTrapForScreens from '@components/FocusTrap/FocusTrapForScreen';
+import useDisableModalDismissOnEscape from '@hooks/useDisableModalDismissOnEscape';
 import useKeyboardShortcut from '@hooks/useKeyboardShortcut';
 import useOnboardingLayout from '@hooks/useOnboardingLayout';
 import useThemeStyles from '@hooks/useThemeStyles';
+import hasCompletedGuidedSetupFlowSelector from '@libs/hasCompletedGuidedSetupFlowSelector';
 import OnboardingModalNavigatorScreenOptions from '@libs/Navigation/AppNavigator/OnboardingModalNavigatorScreenOptions';
 import Navigation from '@libs/Navigation/Navigation';
 import type {OnboardingModalNavigatorParamList} from '@libs/Navigation/types';
@@ -26,15 +28,11 @@ function OnboardingModalNavigator() {
     const styles = useThemeStyles();
     const {shouldUseNarrowLayout} = useOnboardingLayout();
     const [hasCompletedGuidedSetupFlow] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {
-        selector: (onboarding) => {
-            // onboarding is an array for old accounts and accounts created from olddot
-            if (Array.isArray(onboarding)) {
-                return true;
-            }
-            return onboarding?.hasCompletedGuidedSetupFlow;
-        },
+        selector: hasCompletedGuidedSetupFlowSelector,
     });
 
+    useDisableModalDismissOnEscape();
+
     useEffect(() => {
         if (!hasCompletedGuidedSetupFlow) {
             return;
diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx
index 1ee25b45d331..bcca0f0b9247 100644
--- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx
+++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx
@@ -12,7 +12,9 @@ import useTheme from '@hooks/useTheme';
 import useThemeStyles from '@hooks/useThemeStyles';
 import * as Session from '@libs/actions/Session';
 import interceptAnonymousUser from '@libs/interceptAnonymousUser';
-import Navigation from '@libs/Navigation/Navigation';
+import linkingConfig from '@libs/Navigation/linkingConfig';
+import getAdaptedStateFromPath from '@libs/Navigation/linkingConfig/getAdaptedStateFromPath';
+import Navigation, {navigationRef} from '@libs/Navigation/Navigation';
 import type {RootStackParamList, State} from '@libs/Navigation/types';
 import {isCentralPaneName} from '@libs/NavigationUtils';
 import {getChatTabBrickRoad} from '@libs/WorkspacesSettingsUtils';
@@ -54,7 +56,13 @@ function BottomTabBar({selectedTab}: BottomTabBarProps) {
             return;
         }
 
-        Welcome.isOnboardingFlowCompleted({onNotCompleted: () => Navigation.navigate(ROUTES.ONBOARDING_ROOT)});
+        Welcome.isOnboardingFlowCompleted({
+            onNotCompleted: () => {
+                const {adaptedState} = getAdaptedStateFromPath(ROUTES.ONBOARDING_ROOT, linkingConfig.config);
+                navigationRef.resetRoot(adaptedState);
+            },
+        });
+
         // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
     }, [isLoadingApp]);
 
diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts
index a1768df5e0d6..5b3cefb63a2d 100644
--- a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts
+++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts
@@ -1,13 +1,16 @@
-import type {RouterConfigOptions, StackNavigationState} from '@react-navigation/native';
-import {getPathFromState, StackRouter} from '@react-navigation/native';
+import type {CommonActions, RouterConfigOptions, StackActionType, StackNavigationState} from '@react-navigation/native';
+import {findFocusedRoute, getPathFromState, StackRouter} from '@react-navigation/native';
 import type {ParamListBase} from '@react-navigation/routers';
 import getIsNarrowLayout from '@libs/getIsNarrowLayout';
+import * as Localize from '@libs/Localize';
 import getTopmostBottomTabRoute from '@libs/Navigation/getTopmostBottomTabRoute';
 import getTopmostCentralPaneRoute from '@libs/Navigation/getTopmostCentralPaneRoute';
 import linkingConfig from '@libs/Navigation/linkingConfig';
 import getAdaptedStateFromPath from '@libs/Navigation/linkingConfig/getAdaptedStateFromPath';
 import type {NavigationPartialRoute, RootStackParamList, State} from '@libs/Navigation/types';
-import {isCentralPaneName} from '@libs/NavigationUtils';
+import {isCentralPaneName, isOnboardingFlowName} from '@libs/NavigationUtils';
+import * as Welcome from '@userActions/Welcome';
+import CONST from '@src/CONST';
 import NAVIGATORS from '@src/NAVIGATORS';
 import SCREENS from '@src/SCREENS';
 import type {ResponsiveStackNavigatorRouterOptions} from './types';
@@ -97,6 +100,23 @@ function compareAndAdaptState(state: StackNavigationState<RootStackParamList>) {
     }
 }
 
+function shouldPreventReset(state: StackNavigationState<ParamListBase>, action: CommonActions.Action | StackActionType) {
+    if (action.type !== CONST.NAVIGATION_ACTIONS.RESET || !action?.payload) {
+        return false;
+    }
+    const currentFocusedRoute = findFocusedRoute(state);
+    const targetFocusedRoute = findFocusedRoute(action?.payload);
+
+    // We want to prevent the user from navigating back to a non-onboarding screen if they are currently on an onboarding screen
+    if (isOnboardingFlowName(currentFocusedRoute?.name) && !isOnboardingFlowName(targetFocusedRoute?.name)) {
+        Welcome.setOnboardingErrorMessage(Localize.translateLocal('onboarding.purpose.errorBackButton'));
+        // We reset the URL as the browser sets it in a way that doesn't match the navigation state
+        // eslint-disable-next-line no-restricted-globals
+        history.replaceState({}, '', getPathFromState(state, linkingConfig.config));
+        return true;
+    }
+}
+
 function CustomRouter(options: ResponsiveStackNavigatorRouterOptions) {
     const stackRouter = StackRouter(options);
 
@@ -107,6 +127,12 @@ function CustomRouter(options: ResponsiveStackNavigatorRouterOptions) {
             const state = stackRouter.getRehydratedState(partialState, {routeNames, routeParamList, routeGetIdList});
             return state;
         },
+        getStateForAction(state: StackNavigationState<ParamListBase>, action: CommonActions.Action | StackActionType, configOptions: RouterConfigOptions) {
+            if (shouldPreventReset(state, action)) {
+                return state;
+            }
+            return stackRouter.getStateForAction(state, action, configOptions);
+        },
     };
 }
 
diff --git a/src/libs/Navigation/NavigationRoot.tsx b/src/libs/Navigation/NavigationRoot.tsx
index 63792be4f79f..e6da17cf42a5 100644
--- a/src/libs/Navigation/NavigationRoot.tsx
+++ b/src/libs/Navigation/NavigationRoot.tsx
@@ -1,6 +1,7 @@
 import type {NavigationState} from '@react-navigation/native';
 import {DefaultTheme, findFocusedRoute, NavigationContainer} from '@react-navigation/native';
 import React, {useContext, useEffect, useMemo, useRef} from 'react';
+import {useOnyx} from 'react-native-onyx';
 import HybridAppMiddleware from '@components/HybridAppMiddleware';
 import {ScrollOffsetContext} from '@components/ScrollOffsetContextProvider';
 import useActiveWorkspace from '@hooks/useActiveWorkspace';
@@ -8,11 +9,14 @@ import useCurrentReportID from '@hooks/useCurrentReportID';
 import useTheme from '@hooks/useTheme';
 import useWindowDimensions from '@hooks/useWindowDimensions';
 import {FSPage} from '@libs/Fullstory';
+import hasCompletedGuidedSetupFlowSelector from '@libs/hasCompletedGuidedSetupFlowSelector';
 import Log from '@libs/Log';
 import {getPathFromURL} from '@libs/Url';
 import {updateLastVisitedPath} from '@userActions/App';
 import CONST from '@src/CONST';
+import ONYXKEYS from '@src/ONYXKEYS';
 import type {Route} from '@src/ROUTES';
+import ROUTES from '@src/ROUTES';
 import AppNavigator from './AppNavigator';
 import getPolicyIDFromState from './getPolicyIDFromState';
 import linkingConfig from './linkingConfig';
@@ -76,26 +80,44 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady}: N
     const currentReportIDValue = useCurrentReportID();
     const {isSmallScreenWidth} = useWindowDimensions();
     const {setActiveWorkspaceID} = useActiveWorkspace();
+    const [user] = useOnyx(ONYXKEYS.USER);
 
-    const initialState = useMemo(
-        () => {
-            if (!lastVisitedPath) {
-                return undefined;
-            }
+    const [hasCompletedGuidedSetupFlow] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {
+        selector: hasCompletedGuidedSetupFlowSelector,
+    });
 
-            const path = initialUrl ? getPathFromURL(initialUrl) : null;
-
-            // For non-nullable paths we don't want to set initial state
-            if (path) {
-                return;
-            }
+    const initialState = useMemo(() => {
+        if (!user || user.isFromPublicDomain) {
+            return;
+        }
 
-            const {adaptedState} = getAdaptedStateFromPath(lastVisitedPath, linkingConfig.config);
+        // If the user haven't completed the flow, we want to always redirect them to the onboarding flow.
+        // We also make sure that the user is authenticated.
+        if (!hasCompletedGuidedSetupFlow && authenticated) {
+            const {adaptedState} = getAdaptedStateFromPath(ROUTES.ONBOARDING_ROOT, linkingConfig.config);
             return adaptedState;
-        },
+        }
+
+        // If there is no lastVisitedPath, we can do early return. We won't modify the default behavior.
+        if (!lastVisitedPath) {
+            return undefined;
+        }
+
+        const path = initialUrl ? getPathFromURL(initialUrl) : null;
+
+        // If the user opens the root of app "/" it will be parsed to empty string "".
+        // If the path is defined and different that empty string we don't want to modify the default behavior.
+        if (path) {
+            return;
+        }
+
+        // Otherwise we want to redirect the user to the last visited path.
+        const {adaptedState} = getAdaptedStateFromPath(lastVisitedPath, linkingConfig.config);
+        return adaptedState;
+
+        // The initialState value is relevant only on the first render.
         // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
-        [],
-    );
+    }, []);
 
     // https://reactnavigation.org/docs/themes
     const navigationTheme = useMemo(
diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts
index 24af6e52b9f5..a4e3bc91e7ff 100644
--- a/src/libs/Navigation/types.ts
+++ b/src/libs/Navigation/types.ts
@@ -1262,6 +1262,8 @@ type FullScreenName = keyof FullScreenNavigatorParamList;
 
 type CentralPaneName = keyof CentralPaneScreensParamList;
 
+type OnboardingFlowName = keyof OnboardingModalNavigatorParamList;
+
 type SwitchPolicyIDParams = {
     policyID?: string;
     route?: Routes;
@@ -1292,6 +1294,7 @@ export type {
     NewChatNavigatorParamList,
     NewTaskNavigatorParamList,
     OnboardingModalNavigatorParamList,
+    OnboardingFlowName,
     ParticipantsNavigatorParamList,
     PrivateNotesNavigatorParamList,
     ProfileNavigatorParamList,
diff --git a/src/libs/NavigationUtils.ts b/src/libs/NavigationUtils.ts
index 572310e8218b..ea1710b9931c 100644
--- a/src/libs/NavigationUtils.ts
+++ b/src/libs/NavigationUtils.ts
@@ -1,7 +1,7 @@
 import cloneDeep from 'lodash/cloneDeep';
 import SCREENS from '@src/SCREENS';
 import getTopmostBottomTabRoute from './Navigation/getTopmostBottomTabRoute';
-import type {CentralPaneName, RootStackParamList, State} from './Navigation/types';
+import type {CentralPaneName, OnboardingFlowName, RootStackParamList, State} from './Navigation/types';
 
 const CENTRAL_PANE_SCREEN_NAMES = new Set([
     SCREENS.SETTINGS.WORKSPACES,
@@ -17,6 +17,8 @@ const CENTRAL_PANE_SCREEN_NAMES = new Set([
     SCREENS.REPORT,
 ]);
 
+const ONBOARDING_SCREEN_NAMES = new Set([SCREENS.ONBOARDING.PERSONAL_DETAILS, SCREENS.ONBOARDING.PURPOSE, SCREENS.ONBOARDING.WORK, SCREENS.ONBOARDING_MODAL.ONBOARDING]);
+
 const removePolicyIDParamFromState = (state: State<RootStackParamList>) => {
     const stateCopy = cloneDeep(state);
     const bottomTabRoute = getTopmostBottomTabRoute(stateCopy);
@@ -33,4 +35,12 @@ function isCentralPaneName(screen: string | undefined): screen is CentralPaneNam
     return CENTRAL_PANE_SCREEN_NAMES.has(screen as CentralPaneName);
 }
 
-export {isCentralPaneName, removePolicyIDParamFromState};
+function isOnboardingFlowName(screen: string | undefined): screen is OnboardingFlowName {
+    if (!screen) {
+        return false;
+    }
+
+    return ONBOARDING_SCREEN_NAMES.has(screen as OnboardingFlowName);
+}
+
+export {isCentralPaneName, removePolicyIDParamFromState, isOnboardingFlowName};
diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts
index 6758859eab47..1bbc81c2939f 100644
--- a/src/libs/actions/Report.ts
+++ b/src/libs/actions/Report.ts
@@ -1,3 +1,4 @@
+import {findFocusedRoute} from '@react-navigation/native';
 import {format as timezoneFormat, utcToZonedTime} from 'date-fns-tz';
 import {Str} from 'expensify-common';
 import isEmpty from 'lodash/isEmpty';
@@ -55,12 +56,14 @@ import {prepareDraftComment} from '@libs/DraftCommentUtils';
 import * as EmojiUtils from '@libs/EmojiUtils';
 import * as Environment from '@libs/Environment/Environment';
 import * as ErrorUtils from '@libs/ErrorUtils';
+import hasCompletedGuidedSetupFlowSelector from '@libs/hasCompletedGuidedSetupFlowSelector';
 import HttpUtils from '@libs/HttpUtils';
 import isPublicScreenRoute from '@libs/isPublicScreenRoute';
 import * as Localize from '@libs/Localize';
 import Log from '@libs/Log';
 import {registerPaginationConfig} from '@libs/Middleware/Pagination';
-import Navigation from '@libs/Navigation/Navigation';
+import Navigation, {navigationRef} from '@libs/Navigation/Navigation';
+import {isOnboardingFlowName} from '@libs/NavigationUtils';
 import type {NetworkStatus} from '@libs/NetworkConnection';
 import LocalNotification from '@libs/Notification/LocalNotification';
 import Parser from '@libs/Parser';
@@ -2580,28 +2583,47 @@ function openReportFromDeepLink(url: string) {
     // Navigate to the report after sign-in/sign-up.
     InteractionManager.runAfterInteractions(() => {
         Session.waitForUserSignIn().then(() => {
-            Navigation.waitForProtectedRoutes().then(() => {
-                if (route && Session.isAnonymousUser() && !Session.canAnonymousUserAccessRoute(route)) {
-                    Session.signOutAndRedirectToSignIn(true);
-                    return;
-                }
-
-                // We don't want to navigate to the exitTo route when creating a new workspace from a deep link,
-                // because we already handle creating the optimistic policy and navigating to it in App.setUpPoliciesAndNavigate,
-                // which is already called when AuthScreens mounts.
-                if (new URL(url).searchParams.get('exitTo') === ROUTES.WORKSPACE_NEW) {
-                    return;
-                }
-
-                if (shouldSkipDeepLinkNavigation(route)) {
-                    return;
-                }
-
-                if (isAuthenticated) {
-                    return;
-                }
-
-                Navigation.navigate(route as Route, CONST.NAVIGATION.ACTION_TYPE.PUSH);
+            Onyx.connect({
+                key: ONYXKEYS.NVP_ONBOARDING,
+                callback: (onboarding) => {
+                    Navigation.waitForProtectedRoutes().then(() => {
+                        if (route && Session.isAnonymousUser() && !Session.canAnonymousUserAccessRoute(route)) {
+                            Session.signOutAndRedirectToSignIn(true);
+                            return;
+                        }
+
+                        // We don't want to navigate to the exitTo route when creating a new workspace from a deep link,
+                        // because we already handle creating the optimistic policy and navigating to it in App.setUpPoliciesAndNavigate,
+                        // which is already called when AuthScreens mounts.
+                        if (new URL(url).searchParams.get('exitTo') === ROUTES.WORKSPACE_NEW) {
+                            return;
+                        }
+
+                        if (shouldSkipDeepLinkNavigation(route)) {
+                            return;
+                        }
+
+                        const state = navigationRef.getRootState();
+                        const currentFocusedRoute = findFocusedRoute(state);
+                        const hasCompletedGuidedSetupFlow = hasCompletedGuidedSetupFlowSelector(onboarding);
+
+                        // We need skip deeplinking if the user hasn't completed the guided setup flow.
+                        if (!hasCompletedGuidedSetupFlow) {
+                            return;
+                        }
+
+                        if (isOnboardingFlowName(currentFocusedRoute?.name)) {
+                            Welcome.setOnboardingErrorMessage(Localize.translateLocal('onboarding.purpose.errorBackButton'));
+                            return;
+                        }
+
+                        if (isAuthenticated) {
+                            return;
+                        }
+
+                        Navigation.navigate(route as Route, CONST.NAVIGATION.ACTION_TYPE.PUSH);
+                    });
+                },
             });
         });
     });
diff --git a/src/libs/actions/Welcome.ts b/src/libs/actions/Welcome.ts
index 0c3224ee37d9..19797caee1a8 100644
--- a/src/libs/actions/Welcome.ts
+++ b/src/libs/actions/Welcome.ts
@@ -11,7 +11,8 @@ import ROUTES from '@src/ROUTES';
 import type Onboarding from '@src/types/onyx/Onboarding';
 import type TryNewDot from '@src/types/onyx/TryNewDot';
 
-let onboarding: Onboarding | [] | undefined;
+type OnboardingData = Onboarding | [] | undefined;
+
 let isLoadingReportData = true;
 let tryNewDotData: TryNewDot | undefined;
 
@@ -30,8 +31,8 @@ let isServerDataReadyPromise = new Promise<void>((resolve) => {
     resolveIsReadyPromise = resolve;
 });
 
-let resolveOnboardingFlowStatus: (value?: Promise<void>) => void | undefined;
-let isOnboardingFlowStatusKnownPromise = new Promise<void>((resolve) => {
+let resolveOnboardingFlowStatus: (value?: OnboardingData) => void;
+let isOnboardingFlowStatusKnownPromise = new Promise<OnboardingData>((resolve) => {
     resolveOnboardingFlowStatus = resolve;
 });
 
@@ -45,7 +46,7 @@ function onServerDataReady(): Promise<void> {
 }
 
 function isOnboardingFlowCompleted({onCompleted, onNotCompleted}: HasCompletedOnboardingFlowProps) {
-    isOnboardingFlowStatusKnownPromise.then(() => {
+    isOnboardingFlowStatusKnownPromise.then((onboarding) => {
         if (Array.isArray(onboarding) || onboarding?.hasCompletedGuidedSetupFlow === undefined) {
             return;
         }
@@ -102,23 +103,7 @@ function handleHybridAppOnboarding() {
 }
 
 /**
- * Check that a few requests have completed so that the welcome action can proceed:
- *
- * - Whether we are a first time new expensify user
- * - Whether we have loaded all policies the server knows about
- * - Whether we have loaded all reports the server knows about
- * Check if onboarding data is ready in order to check if the user has completed onboarding or not
- */
-function checkOnboardingDataReady() {
-    if (onboarding === undefined) {
-        return;
-    }
-
-    resolveOnboardingFlowStatus?.();
-}
-
-/**
- * Check if user dismissed modal and if report data are loaded
+ * Check if report data are loaded
  */
 function checkServerDataReady() {
     if (isLoadingReportData) {
@@ -143,6 +128,10 @@ function setOnboardingPurposeSelected(value: OnboardingPurposeType) {
     Onyx.set(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED, value ?? null);
 }
 
+function setOnboardingErrorMessage(value: string) {
+    Onyx.set(ONYXKEYS.ONBOARDING_ERROR_MESSAGE, value ?? null);
+}
+
 function setOnboardingAdminsChatReportID(adminsChatReportID?: string) {
     Onyx.set(ONYXKEYS.ONBOARDING_ADMINS_CHAT_REPORT_ID, adminsChatReportID ?? null);
 }
@@ -186,9 +175,7 @@ Onyx.connect({
             return;
         }
 
-        onboarding = value;
-
-        checkOnboardingDataReady();
+        resolveOnboardingFlowStatus(value);
     },
 });
 
@@ -213,10 +200,9 @@ function resetAllChecks() {
     isServerDataReadyPromise = new Promise((resolve) => {
         resolveIsReadyPromise = resolve;
     });
-    isOnboardingFlowStatusKnownPromise = new Promise((resolve) => {
+    isOnboardingFlowStatusKnownPromise = new Promise<OnboardingData>((resolve) => {
         resolveOnboardingFlowStatus = resolve;
     });
-    onboarding = undefined;
     isLoadingReportData = true;
 }
 
@@ -229,4 +215,5 @@ export {
     setOnboardingPolicyID,
     completeHybridAppOnboarding,
     handleHybridAppOnboarding,
+    setOnboardingErrorMessage,
 };
diff --git a/src/libs/hasCompletedGuidedSetupFlowSelector.ts b/src/libs/hasCompletedGuidedSetupFlowSelector.ts
new file mode 100644
index 000000000000..83cde0a0be8c
--- /dev/null
+++ b/src/libs/hasCompletedGuidedSetupFlowSelector.ts
@@ -0,0 +1,12 @@
+import type {OnyxValue} from 'react-native-onyx';
+import type ONYXKEYS from '@src/ONYXKEYS';
+
+function hasCompletedGuidedSetupFlowSelector(onboarding: OnyxValue<typeof ONYXKEYS.NVP_ONBOARDING>): boolean {
+    // onboarding is an array for old accounts and accounts created from olddot
+    if (Array.isArray(onboarding)) {
+        return true;
+    }
+    return onboarding?.hasCompletedGuidedSetupFlow ?? false;
+}
+
+export default hasCompletedGuidedSetupFlowSelector;
diff --git a/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx b/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx
index f5bd14ed7aa1..52e2d817e6db 100644
--- a/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx
+++ b/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx
@@ -1,4 +1,4 @@
-import React, {useCallback, useState} from 'react';
+import React, {useCallback, useEffect, useState} from 'react';
 import {View} from 'react-native';
 import {withOnyx} from 'react-native-onyx';
 import FormProvider from '@components/Form/FormProvider';
@@ -12,7 +12,6 @@ import Text from '@components/Text';
 import TextInput from '@components/TextInput';
 import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails';
 import useAutoFocusInput from '@hooks/useAutoFocusInput';
-import useDisableModalDismissOnEscape from '@hooks/useDisableModalDismissOnEscape';
 import useLocalize from '@hooks/useLocalize';
 import useOnboardingLayout from '@hooks/useOnboardingLayout';
 import useThemeStyles from '@hooks/useThemeStyles';
@@ -46,7 +45,9 @@ function BaseOnboardingPersonalDetails({
     const [shouldValidateOnChange, setShouldValidateOnChange] = useState(false);
     const {accountID} = useSession();
 
-    useDisableModalDismissOnEscape();
+    useEffect(() => {
+        Welcome.setOnboardingErrorMessage('');
+    }, []);
 
     const completeEngagement = useCallback(
         (values: FormOnyxValues<'onboardingPersonalDetailsForm'>) => {
diff --git a/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx b/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx
index 03a4b790bc5f..7304c1822ae9 100644
--- a/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx
+++ b/src/pages/OnboardingPurpose/BaseOnboardingPurpose.tsx
@@ -2,7 +2,7 @@ import {useIsFocused} from '@react-navigation/native';
 import React, {useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState} from 'react';
 import {View} from 'react-native';
 import {ScrollView} from 'react-native-gesture-handler';
-import {withOnyx} from 'react-native-onyx';
+import {useOnyx} from 'react-native-onyx';
 import FormAlertWithSubmitButton from '@components/FormAlertWithSubmitButton';
 import HeaderWithBackButton from '@components/HeaderWithBackButton';
 import Icon from '@components/Icon';
@@ -13,7 +13,6 @@ import MenuItemList from '@components/MenuItemList';
 import OfflineIndicator from '@components/OfflineIndicator';
 import SafeAreaConsumer from '@components/SafeAreaConsumer';
 import Text from '@components/Text';
-import useDisableModalDismissOnEscape from '@hooks/useDisableModalDismissOnEscape';
 import useLocalize from '@hooks/useLocalize';
 import useOnboardingLayout from '@hooks/useOnboardingLayout';
 import useTheme from '@hooks/useTheme';
@@ -28,7 +27,8 @@ import type {OnboardingPurposeType} from '@src/CONST';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
 import ROUTES from '@src/ROUTES';
-import type {BaseOnboardingPurposeOnyxProps, BaseOnboardingPurposeProps} from './types';
+import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue';
+import type {BaseOnboardingPurposeProps} from './types';
 
 const menuIcons = {
     [CONST.ONBOARDING_CHOICES.EMPLOYER]: Illustrations.ReceiptUpload,
@@ -38,15 +38,15 @@ const menuIcons = {
     [CONST.ONBOARDING_CHOICES.LOOKING_AROUND]: Illustrations.Binoculars,
 };
 
-function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, onboardingPurposeSelected}: BaseOnboardingPurposeProps) {
+function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight}: BaseOnboardingPurposeProps) {
     const styles = useThemeStyles();
     const {translate} = useLocalize();
     const {shouldUseNarrowLayout} = useOnboardingLayout();
     const [selectedPurpose, setSelectedPurpose] = useState<OnboardingPurposeType | undefined>(undefined);
     const {isSmallScreenWidth, windowHeight} = useWindowDimensions();
     const theme = useTheme();
-
-    useDisableModalDismissOnEscape();
+    const [onboardingPurposeSelected, onboardingPurposeSelectedResult] = useOnyx(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED);
+    const [onboardingErrorMessage, onboardingErrorMessageResult] = useOnyx(ONYXKEYS.ONBOARDING_ERROR_MESSAGE);
 
     const PurposeFooterInstance = <OfflineIndicator />;
 
@@ -83,8 +83,6 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, on
         Navigation.navigate(ROUTES.ONBOARDING_PERSONAL_DETAILS);
     }, [selectedPurpose]);
 
-    const [errorMessage, setErrorMessage] = useState<string>('');
-
     const menuItems: MenuItemProps[] = Object.values(CONST.ONBOARDING_CHOICES).map((choice) => {
         const translationKey = `onboarding.purpose.${choice}` as const;
         const isSelected = selectedPurpose === choice;
@@ -103,7 +101,7 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, on
             numberOfLinesTitle: 0,
             onPress: () => {
                 Welcome.setOnboardingPurposeSelected(choice);
-                setErrorMessage('');
+                Welcome.setOnboardingErrorMessage('');
             },
         };
     });
@@ -111,15 +109,18 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, on
 
     const handleOuterClick = useCallback(() => {
         if (!selectedPurpose) {
-            setErrorMessage(translate('onboarding.purpose.errorSelection'));
+            Welcome.setOnboardingErrorMessage(translate('onboarding.purpose.errorSelection'));
         } else {
-            setErrorMessage(translate('onboarding.purpose.errorContinue'));
+            Welcome.setOnboardingErrorMessage(translate('onboarding.purpose.errorContinue'));
         }
-    }, [selectedPurpose, setErrorMessage, translate]);
+    }, [selectedPurpose, translate]);
 
     const onboardingLocalRef = useRef<TOnboardingRef>(null);
     useImperativeHandle(isFocused ? OnboardingRefManager.ref : onboardingLocalRef, () => ({handleOuterClick}), [handleOuterClick]);
 
+    if (isLoadingOnyxValue(onboardingPurposeSelectedResult, onboardingErrorMessageResult)) {
+        return null;
+    }
     return (
         <SafeAreaConsumer>
             {({safeAreaPaddingBottomStyle}) => (
@@ -148,14 +149,14 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, on
                         buttonText={translate('common.continue')}
                         onSubmit={() => {
                             if (!selectedPurpose) {
-                                setErrorMessage(translate('onboarding.purpose.errorSelection'));
+                                Welcome.setOnboardingErrorMessage(translate('onboarding.purpose.errorSelection'));
                                 return;
                             }
-                            setErrorMessage('');
+                            Welcome.setOnboardingErrorMessage('');
                             saveAndNavigate();
                         }}
-                        message={errorMessage}
-                        isAlertVisible={!!errorMessage}
+                        message={onboardingErrorMessage}
+                        isAlertVisible={!!onboardingErrorMessage}
                         containerStyles={[styles.w100, styles.mb5, styles.mh0, paddingHorizontal]}
                     />
                 </View>
@@ -166,10 +167,6 @@ function BaseOnboardingPurpose({shouldUseNativeStyles, shouldEnableMaxHeight, on
 
 BaseOnboardingPurpose.displayName = 'BaseOnboardingPurpose';
 
-export default withOnyx<BaseOnboardingPurposeProps, BaseOnboardingPurposeOnyxProps>({
-    onboardingPurposeSelected: {
-        key: ONYXKEYS.ONBOARDING_PURPOSE_SELECTED,
-    },
-})(BaseOnboardingPurpose);
+export default BaseOnboardingPurpose;
 
 export type {BaseOnboardingPurposeProps};
diff --git a/src/pages/OnboardingPurpose/types.ts b/src/pages/OnboardingPurpose/types.ts
index 8c8f11503f1a..17970dbab9a6 100644
--- a/src/pages/OnboardingPurpose/types.ts
+++ b/src/pages/OnboardingPurpose/types.ts
@@ -1,20 +1,11 @@
-import type {OnyxEntry} from 'react-native-onyx';
-import type {OnboardingPurposeType} from '@src/CONST';
-
 type OnboardingPurposeProps = Record<string, unknown>;
 
-type BaseOnboardingPurposeOnyxProps = {
-    /** Saved onboarding purpose selected by the user */
-    onboardingPurposeSelected: OnyxEntry<OnboardingPurposeType>;
-};
-
-type BaseOnboardingPurposeProps = OnboardingPurposeProps &
-    BaseOnboardingPurposeOnyxProps & {
-        /* Whether to use native styles tailored for native devices */
-        shouldUseNativeStyles: boolean;
+type BaseOnboardingPurposeProps = OnboardingPurposeProps & {
+    /* Whether to use native styles tailored for native devices */
+    shouldUseNativeStyles: boolean;
 
-        /** Whether to use the maxHeight (true) or use the 100% of the height (false) */
-        shouldEnableMaxHeight: boolean;
-    };
+    /** Whether to use the maxHeight (true) or use the 100% of the height (false) */
+    shouldEnableMaxHeight: boolean;
+};
 
-export type {BaseOnboardingPurposeOnyxProps, BaseOnboardingPurposeProps, OnboardingPurposeProps};
+export type {BaseOnboardingPurposeProps, OnboardingPurposeProps};
diff --git a/src/pages/OnboardingWork/BaseOnboardingWork.tsx b/src/pages/OnboardingWork/BaseOnboardingWork.tsx
index 9b8824300d30..14f9223f6c67 100644
--- a/src/pages/OnboardingWork/BaseOnboardingWork.tsx
+++ b/src/pages/OnboardingWork/BaseOnboardingWork.tsx
@@ -9,7 +9,6 @@ import KeyboardAvoidingView from '@components/KeyboardAvoidingView';
 import OfflineIndicator from '@components/OfflineIndicator';
 import Text from '@components/Text';
 import TextInput from '@components/TextInput';
-import useDisableModalDismissOnEscape from '@hooks/useDisableModalDismissOnEscape';
 import useLocalize from '@hooks/useLocalize';
 import useOnboardingLayout from '@hooks/useOnboardingLayout';
 import useThemeStyles from '@hooks/useThemeStyles';
@@ -33,8 +32,6 @@ function BaseOnboardingWork({shouldUseNativeStyles, onboardingPurposeSelected, o
     const {isSmallScreenWidth} = useWindowDimensions();
     const {shouldUseNarrowLayout} = useOnboardingLayout();
 
-    useDisableModalDismissOnEscape();
-
     const completeEngagement = useCallback(
         (values: FormOnyxValues<'onboardingWorkForm'>) => {
             if (!onboardingPurposeSelected) {
diff --git a/tests/ui/UnreadIndicatorsTest.tsx b/tests/ui/UnreadIndicatorsTest.tsx
index b10cae2e7736..ca30eb10b065 100644
--- a/tests/ui/UnreadIndicatorsTest.tsx
+++ b/tests/ui/UnreadIndicatorsTest.tsx
@@ -39,6 +39,10 @@ jest.mock('../../src/components/ConfirmedRoute.tsx');
 TestHelper.setupApp();
 TestHelper.setupGlobalFetchMock();
 
+beforeEach(() => {
+    Onyx.set(ONYXKEYS.NVP_ONBOARDING, {hasCompletedGuidedSetupFlow: true});
+});
+
 function scrollUpToRevealNewMessagesBadge() {
     const hintText = Localize.translateLocal('sidebarScreen.listOfChatMessages');
     fireEvent.scroll(screen.getByLabelText(hintText), {
