{"record":{"id":"77d10aceee89a82a","repo":"dotnet/maui","slug":"changing-the-current-page-is-only-allowed-if-it-s","errorCode":null,"errorMessage":"Changing the current page is only allowed if it's being called from the same UI thread.Please ensure that the new page is in the same UI thread as the current page.","messagePattern":"Changing the current page is only allowed if it's being called from the same UI thread\\.Please ensure that the new page is in the same UI thread as the current page\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Compatibility/Core/src/Windows/Platform.cs","lineNumber":425,"sourceCode":"\t\t\t\tnewPage.Layout(ContainerBounds);\n\n\t\t\t\tAddPage(newPage);\n\n\t\t\t\tcompletedCallback?.Invoke();\n\n\t\t\t\t_currentPage = newPage;\n\n\t\t\t\tUpdateToolbarTracker();\n\n\t\t\t\tawait UpdateToolbarItems();\n\t\t\t}\n\t\t\tcatch (Exception error)\n\t\t\t{\n\t\t\t\t//This exception prevents the Main Page from being changed in a child \n\t\t\t\t//window or a different thread, except on the Main thread. \n\t\t\t\t//HEX 0x8001010E \n\t\t\t\tif (error.HResult == -2147417842)\n\t\t\t\t\tthrow new InvalidOperationException(\"Changing the current page is only allowed if it's being called from the same UI thread.\" +\n\t\t\t\t\t\t\"Please ensure that the new page is in the same UI thread as the current page.\");\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\n\t\tvoid RemovePage(Page page)\n\t\t{\n\t\t\tif (_container == null || page == null)\n\t\t\t\treturn;\n\n\t\t\t_modalBackgroundPage?.GetCurrentPage()?.SendAppearing();\n\n\t\t\tIVisualElementRenderer pageRenderer = GetRenderer(page);\n\n#pragma warning disable RS0030 // Do not use banned APIs; Panel.Children is banned for performance reasons.\n\t\t\tif (_container.Children.Contains(pageRenderer.ContainerElement))\n\t\t\t\t_container.Children.Remove(pageRenderer.ContainerElement);\n#pragma warning restore RS0030 // Do not use banned APIs","sourceCodeStart":407,"sourceCodeEnd":443,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/src/Compatibility/Core/src/Windows/Platform.cs#L407-L443","documentation":"SetCurrent catches exceptions during page transitions and checks for HResult 0x8001010E (RPC_E_WRONG_THREAD). When this HResult is detected, it rethrows as InvalidOperationException with a descriptive message. This fires when code attempts to change the current page from a thread other than the UI thread, violating WinUI/UWP threading rules.","triggerScenarios":"A background task, async continuation, timer callback, or event handler on a non-UI thread calls navigation methods or directly changes MainPage. The SetCurrent method performs UI operations (Layout, AddPage, UpdateToolbarItems) that require the UI thread.","commonSituations":"Task.Run callback modifies UI without Dispatcher marshalling; MessagingCenter subscriber runs on background thread and triggers navigation; event from native WinUI component fires on non-UI thread; long-running async operation's continuation loses the SynchronizationContext.","solutions":["Marshal navigation calls to the UI thread: Device.BeginInvokeOnMainThread(async () => await Navigation.PushAsync(page))","Use Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => ...) in WinUI code","Capture SynchronizationContext or use ConfigureAwait(true) to ensure continuations run on UI thread","Avoid calling any page-changing API from Task.Run or background event handlers"],"exampleFix":"// before\nTask.Run(() => {\n    // runs on thread pool — throws RPC_E_WRONG_THREAD\n    Application.Current.MainPage = new DifferentPage();\n});\n\n// after\nDevice.BeginInvokeOnMainThread(() => {\n    Application.Current.MainPage = new DifferentPage();\n});","handlingStrategy":"try-catch","validationCode":"// Before any page change from async/background context, marshal to UI thread\nDevice.BeginInvokeOnMainThread(() =>\n{\n    Application.Current.MainPage = newPage;\n});","typeGuard":null,"tryCatchPattern":"try\n{\n    await SetCurrentAsync(newPage);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"same UI thread\"))\n{\n    // Retry on UI thread\n    Device.BeginInvokeOnMainThread(() =>\n    {\n        Application.Current.MainPage = newPage;\n    });\n}","preventionTips":["Always wrap page-changing calls from async callbacks in Device.BeginInvokeOnMainThread","Avoid calling navigation from Task.Run or background event handlers","Capture and use SynchronizationContext or Dispatcher for UI-thread marshalling","Audit all navigation call sites for thread safety in code review"],"tags":["threading","ui-thread","concurrency","winui","uwp","maui-compatibility"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}