{"record":{"id":"3ca93a99d367893d","repo":"dotnet/wpf","slug":"sr-requiressta","errorCode":null,"errorMessage":"SR.RequiresSTA","messagePattern":"SR\\.RequiresSTA","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/InputManager.cs","lineNumber":144,"sourceCode":"            if (inputManager == null)\n            {\n                inputManager = new InputManager();\n                dispatcher.InputManager = inputManager;\n            }\n\n            return inputManager;\n        }\n\n        private InputManager()\n        {\n            // STA Requirement\n            //\n            // Avalon doesn't necessarily require STA, but many components do.  Examples\n            // include Cicero, OLE, COM, etc.  So we throw an exception here if the\n            // thread is not STA.\n            if(Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)\n            {\n                throw new InvalidOperationException(SR.RequiresSTA);\n            }\n\n            _stagingArea = new Stack();\n\n            _primaryKeyboardDevice = new Win32KeyboardDevice(this);\n            _primaryMouseDevice = new Win32MouseDevice(this);\n            _primaryCommandDevice = new CommandDevice(this);\n\n            _continueProcessingStagingAreaCallback = new DispatcherOperationCallback(ContinueProcessingStagingArea);\n\n            _hitTestInvalidatedAsyncOperation = null;\n            _hitTestInvalidatedAsyncCallback = new DispatcherOperationCallback(HitTestInvalidatedAsyncCallback);\n\n            _layoutUpdatedCallback = new EventHandler(OnLayoutUpdated); //need to cache it, LM only keeps weak ref\n            ContextLayoutManager.From(Dispatcher).LayoutEvents.Add(_layoutUpdatedCallback);\n\n            // Timer used to synchronize the input devices periodically\n            _inputTimer = new DispatcherTimer(DispatcherPriority.Background);","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/InputManager.cs#L126-L162","documentation":"The InputManager constructor throws InvalidOperationException(SR.RequiresSTA) when constructed on a thread whose apartment state is not STA. WPF input relies heavily on STA-only components (Cicero/TSF, OLE, COM). InputManager is created implicitly by UI infrastructure, so this fires when a control or input-related object is first touched on an MTA or background thread.","triggerScenarios":"Creating a UIElement, Dispatcher-operated input object, or instantiating InputManager directly on a thread started without SetApartmentState(ApartmentState.STA), e.g. a plain ThreadPool or Task thread.","commonSituations":"Creating WPF controls on background threads; running UI code in console apps or services without [STAThread]; unit test runners that use MTA threads; migrating WinForms interop code to async continuation threads.","solutions":["Mark the main entry point with [STAThread] attribute.","On manually created threads, call thread.SetApartmentState(ApartmentState.STA) before thread.Start().","Marshal all UI/input object creation onto the existing STA UI thread via Dispatcher.Invoke/InvokeAsync.","Never create WPF visual/input objects inside Task.Run or ThreadPool work items."],"exampleFix":"// before\nvar t = new Thread(() => new Window().Show()); t.Start();\n// after\nvar t = new Thread(() => new Window().Show());\nt.SetApartmentState(ApartmentState.STA);\nt.Start();","handlingStrategy":"validation","validationCode":"if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)\n    throw new InvalidOperationException(\"UI creation requires an STA thread\");","typeGuard":"static bool IsStaThread() => Thread.CurrentThread.GetApartmentState() == ApartmentState.STA;","tryCatchPattern":"try { CreateUiOnThisThread(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"STA\"))\n{ Dispatcher.CurrentDispatcher.Invoke(CreateUiOnThisThread); }","preventionTips":["Always annotate Main with [STAThread] in WPF applications.","Call SetApartmentState(ApartmentState.STA) on any thread that touches WPF objects.","Never construct WPF visuals inside Task.Run or thread-pool continuations; use Dispatcher.Invoke."],"tags":["wpf","threading","sta","com"],"backgroundTag":"unsupported-thread-apartment","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}