dotnet/maui · error · InvalidOperationException

Unable to get window from parent view controller

Error message

Unable to get window from parent view controller

What it means

This sample MainViewController (MacCatalyst) embeds a MAUI view inside a UIKit UI. It retrieves the parent UIWindow via `ParentViewController?.View?.Window`. If the controller is not yet in the view hierarchy (no parent, or the parent's view has no window), the window is null and embedding cannot proceed because the scenario requires a concrete UIWindow to host the MAUI root view.

Source

Thrown at src/Controls/samples/Controls.Sample.Embedding/Platforms/MacCatalyst/MainViewController.cs:50

			stackView.TrailingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TrailingAnchor, -20),
			stackView.BottomAnchor.ConstraintLessThanOrEqualTo(View.SafeAreaLayoutGuide.BottomAnchor, -20)
		});

		// Create UIKit button
		var firstButton = new UIButton(UIButtonType.System);
		firstButton.SetTitle("UIKit Button Above MAUI", UIControlState.Normal);
		stackView.AddArrangedSubview(firstButton);

		// Uncomment the scenario to test:
		//_scenario = new EmbeddingScenarios.Scenario1_Basic();
		//_scenario = new EmbeddingScenarios.Scenario2_Scoped();
		_scenario = new EmbeddingScenarios.Scenario3_Correct();

		// create the view and (maybe) the window
		var window = ParentViewController?.View?.Window;
		if (window is null)
		{
			throw new InvalidOperationException("Unable to get window from parent view controller");
		}

		(_mauiView, _nativeView) = _scenario.Embed(window);

		// add the new view to the UI
		stackView.AddArrangedSubview(new ContainerView(_nativeView));

		// Create UIKit button
		var secondButton = new UIButton(UIButtonType.System);
		secondButton.SetTitle("UIKit Button Below MAUI", UIControlState.Normal);
		stackView.AddArrangedSubview(secondButton);

		// Create UIKit button
		var thirdButton = new UIButton(UIButtonType.System);
		thirdButton.SetTitle("UIKit Button Magic", UIControlState.Normal);
		thirdButton.TouchUpInside += OnMagicClicked;
		stackView.AddArrangedSubview(thirdButton);

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Move the embedding logic to ViewDidAppear or viewWillAppear, where the view hierarchy (including Window) is guaranteed to be set up.
  2. Ensure the controller is presented as a child of a window-backed parent controller before this code runs.
  3. Guard with a retry or deferred execution if the window is not yet available.

Example fix

// before (ViewDidLoad — window may be null)
var window = ParentViewController?.View?.Window;
if (window is null) throw new InvalidOperationException(...);

// after (ViewDidAppear — window is available)
public override void ViewDidAppear(bool animated)
{
    base.ViewDidAppear(animated);
    var window = ParentViewController?.View?.Window;
    if (window is null) return; // not ready yet
    (_mauiView, _nativeView) = _scenario.Embed(window);
}
Defensive patterns

Strategy: validation

Validate before calling

// Defer embedding until the window is available
var window = ParentViewController?.View?.Window;
if (window is null)
    return; // will be available in ViewDidAppear
(_mauiView, _nativeView) = _scenario.Embed(window);

Prevention

When it happens

Trigger: Accessing this code path during ViewDidLoad when the controller has not yet been added to the window hierarchy. Calling Embed before the view is added as a child of a window-backed controller. Using the controller outside of a normal presentation flow.

Common situations: Presenting the controller programmatically before it is attached to a window. Lifecycle timing issues where ViewDidLoad fires before the parent's View.Window is available. Testing the controller in isolation without a full window setup.

Related errors


AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13). Data as JSON: /api/errors/f3067f305be142ba. Report an issue: GitHub.