microsoft/semantic-kernel · error · InvalidOperationException
Application is already running.
Error message
Application is already running.
What it means
AgentsApp.StartAsync uses Interlocked.Exchange on _runningCount as a single-entry guard: if it was already 1, it throws InvalidOperationException. The app is a singleton-style host wrapper, so it may only be started once until ShutdownAsync resets the counter to 0.
Source
Thrown at dotnet/src/Agents/Runtime/Core/AgentsApp.cs:56
/// <summary>
/// Gets the application lifetime object to manage startup and shutdown events.
/// </summary>
public IHostApplicationLifetime ApplicationLifetime => this.Services.GetRequiredService<IHostApplicationLifetime>();
/// <summary>
/// Gets the agent runtime responsible for handling agent messaging and operations.
/// </summary>
public IAgentRuntime AgentRuntime => this.Services.GetRequiredService<IAgentRuntime>();
/// <summary>
/// Starts the application by initiating the host.
/// Throws an exception if the application is already running.
/// </summary>
public async ValueTask StartAsync()
{
if (Interlocked.Exchange(ref this._runningCount, 1) != 0)
{
throw new InvalidOperationException("Application is already running.");
}
await this.Host.StartAsync().ConfigureAwait(false);
}
/// <summary>
/// Shuts down the application by stopping the host.
/// Throws an exception if the application is not running.
/// </summary>
public async ValueTask ShutdownAsync()
{
if (Interlocked.Exchange(ref this._runningCount, 0) != 1)
{
throw new InvalidOperationException("Application is already stopped.");
}
await this.Host.StopAsync().ConfigureAwait(false);
}View on GitHub (pinned to c028a0c7dc)
Solutions
- Call StartAsync exactly once, or rely solely on PublishMessageAsync's auto-start and skip explicit StartAsync.
- Guard with your own started flag or check the application lifetime state before calling StartAsync.
- Ensure ShutdownAsync completes before attempting to restart.
Example fix
// before await app.StartAsync(); await app.PublishMessageAsync(msg, topic); // fine, already running await app.StartAsync(); // throws // after await app.StartAsync(); // do not start again; publish directly await app.PublishMessageAsync(msg, topic);
Defensive patterns
Strategy: validation
Validate before calling
// AgentsApp exposes no public IsRunning; track via your own flag or rely on PublishMessageAsync auto-start.
bool started = false;
async ValueTask EnsureStartedAsync(AgentsApp app)
{
if (started) return;
try { await app.StartAsync(); started = true; }
catch (InvalidOperationException) { started = true; /* already running */ }
} Try / catch
try { await app.StartAsync(); }
catch (InvalidOperationException) { /* already running; safe to continue publishing */ } Prevention
- Choose one startup strategy: either explicit StartAsync once, or rely on PublishMessageAsync auto-start.
- Centralize app startup in composition root to avoid multiple callers starting.
- Avoid calling StartAsync from concurrent initialization paths.
When it happens
Trigger: Calling StartAsync twice without an intervening ShutdownAsync; calling PublishMessageAsync (which auto-starts the host when _runningCount==0) and then explicitly calling StartAsync; a hosted-service/DI lifecycle starting the app and application code starting it again.
Common situations: Double initialization in ASP.NET host startup; mixing the auto-start path of PublishMessageAsync with an explicit StartAsync; retries that re-enter startup.
Related errors
- Application is already stopped.
- Runtime is already running.
- Invalid AgentId key: '{key}'. Must only contain ASCII charac
- Invalid AgentId type: '{type}'. Must be alphanumeric (a-z, 0
- Invalid key-value pair format: {inputPair}; expecting "{keyN
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/58ea32ed388cbee3.
Report an issue: GitHub.