stride3d/stride · error · ApplicationException

Update requested without a Launcher Window. Cannot continue!

Error message

Update requested without a Launcher Window. Cannot continue!

What it means

The Stride Launcher's self-update flow shows the self-update window as a dialog anchored to the launcher's main window. If Application.Current is not an App with a non-null MainWindow (or no WPF Application exists at all), SelfUpdater refuses to continue because there is no owner window for the modal dialog. The exception is thrown inside the update Task, so it surfaces as a faulted task rather than synchronously.

Solutions

  1. Ensure the launcher's MainWindow is created, assigned, and shown before invoking SelfUpdate
  2. Guard the update trigger: only allow self-update when Application.Current is App with a non-null MainWindow
  3. If no window exists, surface a normal window-less update path or prompt the user to reopen the launcher
  4. Catch the faulted task in the caller and log a user-friendly message instead of crashing

Example fix

// before
selfUpdateButton.Command = UpdateNow; // can run before window ready
// after
if (Application.Current is App { MainWindow: Window window } && window.IsLoaded)
    UpdateNow();
else
    MessageBox.Show("Cannot update: launcher window is not available.");
Defensive patterns

Strategy: validation

Validate before calling

bool canSelfUpdate = Application.Current is App { MainWindow: Window { IsLoaded: true } };

Type guard

static bool HasLauncherWindow() => Application.Current is App { MainWindow: Window window };

Try / catch

try { await SelfUpdate(); } catch (ApplicationException ex) when (ex.Message.Contains("Launcher Window")) { ShowUpdateUnavailableMessage(); }

Prevention

When it happens

Trigger: Calling SelfUpdate (which calls UpdateLauncherFiles) while the launcher has no initialized MainWindow: the window is still loading, was closed, the App instance is not the derived App type, or the method is invoked from a headless/CLI context where Application.Current is null.

Common situations: Launching the update very early at startup before MainWindow is assigned; triggering an auto-update after the main window was closed; running the updater in tests or automation without a WPF Application; a custom App class not matching the 'App { MainWindow: Window }' pattern.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/6b2f67b3f72ef9b6. Report an issue: GitHub.

Appendix: source

Thrown at sources/launcher/Stride.Launcher/Services/SelfUpdater.cs:169

        // Check to see if an update is needed
        if (package is null || version >= new PackageVersion(package.Version.Version, package.Version.SpecialVersion))
        {
            return;
        }

        // Display progress window
        await dispatcher.InvokeAsync(() =>
        {
            selfUpdateWindow = new();
            selfUpdateWindow.LockWindow();
            if (Application.Current is App { MainWindow: Window window })
            {
                _ = selfUpdateWindow.ShowDialog(window); // we don't await on purpose here
            }
            else
            {
                throw new ApplicationException("Update requested without a Launcher Window. Cannot continue!");
            }
        }, cancellationToken);

        var movedFiles = new List<string>();

        // Download package
        var installedPackage = await store.InstallPackage(package.Id, package.Version, package.TargetFrameworks, null);

        // Copy files from tools\ to the current directory
        var inputFiles = installedPackage.GetFiles();

        // TODO: We should get list of previous files from nuspec (store it as a resource and open it with NuGet API maybe?)
        // TODO: For now, we deal only with the App.config file since we won't be able to fix it afterward.
        var exeLocation = Program.GetExecutablePath();
        var exeDirectory = Path.GetDirectoryName(exeLocation)!;
        const string directoryRoot = "tools/"; // Important!: this is matching where files are store in the nuspec
        try
        {

View on GitHub (pinned to 96fad776d2)