microsoft/autogen · error · InvalidOperationException
Application is already stopped.
Error message
Application is already stopped.
What it means
Thrown by AgentsApp.ShutdownAsync when the runningCount flag shows the app is not currently running. Shutdown is only valid after a successful StartAsync (explicit or implicit via PublishMessageAsync auto-start); stopping twice, or stopping before any start, throws.
Source
Thrown at dotnet/src/Microsoft.AutoGen/Core/AgentsApp.cs:121
private int runningCount;
public async ValueTask StartAsync()
{
if (Interlocked.Exchange(ref this.runningCount, 1) != 0)
{
throw new InvalidOperationException("Application is already running.");
}
Debug.Assert(this.AgentRuntime != null);
await this.Host.StartAsync();
}
public async ValueTask ShutdownAsync()
{
if (Interlocked.Exchange(ref this.runningCount, 0) != 1)
{
throw new InvalidOperationException("Application is already stopped.");
}
await this.Host.StopAsync();
}
public async ValueTask PublishMessageAsync<TMessage>(TMessage message, TopicId topic, string? messageId = null, CancellationToken cancellationToken = default)
where TMessage : notnull
{
if (Volatile.Read(ref this.runningCount) == 0)
{
await this.StartAsync();
}
await this.AgentRuntime.PublishMessageAsync(message, topic, messageId: messageId, cancellationToken: cancellationToken);
}
public Task WaitForShutdownAsync()
{View on GitHub (pinned to 027ecf0a37)
Solutions
- Track whether you started the app and call ShutdownAsync only once from its owner
- Remove duplicate shutdown registrations — let either the host lifetime or your explicit call stop it, not both
- Guard shutdown with the same running-state flag the app exposes rather than calling unconditionally
Example fix
// before
try { await app.PublishMessageAsync(m, t); }
finally { await app.ShutdownAsync(); } // also stopped by host -> throws
// after
bool started = false;
try { await app.StartAsync(); started = true; await app.PublishMessageAsync(m, t); }
finally { if (started) { await app.ShutdownAsync(); } } Defensive patterns
Strategy: validation
Validate before calling
if (appRunning) { await app.ShutdownAsync(); appRunning = false; } Try / catch
try { await app.ShutdownAsync(); } catch (InvalidOperationException ex) when (ex.Message == "Application is already stopped.") { _logger.LogDebug("App already stopped"); } Prevention
- Pair every StartAsync with exactly one ShutdownAsync using a flag
- Avoid double shutdown from both finally blocks and host lifetime hooks
When it happens
Trigger: Calling ShutdownAsync before StartAsync was ever invoked; calling ShutdownAsync twice (e.g. once in a finally block and once in an IHostedService stop path); PublishMessageAsync auto-start racing a concurrent shutdown.
Common situations: Cleanup code in finally blocks running after the host already stopped the app; multiple shutdown hooks registered (DI disposal plus explicit call); exception paths that trigger shutdown of a never-started app.
Related errors
- Runtime is not running.
- Kernel is not running
- Installing directory is not set
- The group chat has not been initialized. It must be run befo
- Error initializing: {this.GetType().FullName}; already initi
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/b0a201863150a796.
Report an issue: GitHub.