dotnet/wpf · error · InvalidOperationException
SR.ShutdownModeWhenAppShutdown
Error message
SR.ShutdownModeWhenAppShutdown
What it means
ShutdownMode cannot be changed once the application has begun shutting down or is fully shut down. The setter throws InvalidOperationException(SR.ShutdownModeWhenAppShutdown) when IsShuttingDown or _appIsShutdown is true. This protects the shutdown sequence from contradictory configuration mid-flight.
Solutions
- Set ShutdownMode during application startup, before Run() is invoked
- Guard the assignment with Application.Current.Dispatcher.HasShutdownStarted checks
- Move the setting out of Exit/Closed handlers into App constructor or OnStartup
- If the app already shut down, create a new Application instance instead of reconfiguring the old one
Example fix
// before
protected override void OnExit(ExitEventArgs e)
{
Current.ShutdownMode = ShutdownMode.OnExplicitShutdown; // throws
}
// after
public App()
{
ShutdownMode = ShutdownMode.OnExplicitShutdown;
} Defensive patterns
Strategy: type-guard
Validate before calling
bool canSetMode() => Application.Current != null && !Application.Current.Dispatcher.HasShutdownStarted;
Type guard
bool ShutdownPending(Application app) => app.Dispatcher.HasShutdownStarted;
Try / catch
try { app.ShutdownMode = mode; } catch (InvalidOperationException) { /* app is shutting down; skip */ } Prevention
- Set ShutdownMode in the App constructor or OnStartup
- Never set it in Exit/Closed handlers
- Check HasShutdownStarted before configuring
- Keep shutdown configuration at startup code paths only
When it happens
Trigger: Assigning Application.ShutdownMode from within the Exit event handler, after Shutdown() has been called, inside a Window.Closed handler during app teardown, or on a restarted-but-disposed Application instance.
Common situations: Cleanup code in OnExit trying to force OnExplicitShutdown; re-running logic after Application.Run returned; event handlers fired during shutdown cascades.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- SR.ApplicationShuttingDown
- SR.Format(SR.BindingExpressionStatusChanged, _status…
- SR.Format(SR.CannotCallRunMultipleTimes…
- SR.Storyboard_NeverApplied
- SR.UndoNoOpenParentUnit
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/ea628c28f99a64fd.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Application.cs:840
/// </summary>
public ShutdownMode ShutdownMode
{
get
{
VerifyAccess();
return _shutdownMode;
}
set
{
VerifyAccess();
if ( !IsValidShutdownMode(value) )
{
throw new InvalidEnumArgumentException("value", (int)value, typeof(ShutdownMode));
}
if (IsShuttingDown || _appIsShutdown)
{
throw new InvalidOperationException(SR.ShutdownModeWhenAppShutdown);
}
_shutdownMode = value;
}
}
/// <summary>
/// Current locally defined Resources
/// </summary>
[Ambient]
public ResourceDictionary Resources
{
//Don't use VerifyAccess() here since Resources can be set from any thread.
//We synchronize access using _globalLock
get
{
ResourceDictionary resources;View on GitHub (pinned to 81131a70a4)