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
- Ensure the launcher's MainWindow is created, assigned, and shown before invoking SelfUpdate
- Guard the update trigger: only allow self-update when Application.Current is App with a non-null MainWindow
- If no window exists, surface a normal window-less update path or prompt the user to reopen the launcher
- 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
- Only expose update commands after the window is loaded
- Add a can-execute guard on the update command checking MainWindow
- Test self-update in headless/automation mode to catch ordering issues
- Never close the main window while an update is pending
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
- ArgumentNullException: value
- Value cannot be null. (Parameter 'getParentFunc')
- The path [ ] contains access to a member of a null object.
- Unable to retrieve the value of this member path on this…
- url cannot be null or empty.
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)