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

  1. Call StartAsync exactly once, or rely solely on PublishMessageAsync's auto-start and skip explicit StartAsync.
  2. Guard with your own started flag or check the application lifetime state before calling StartAsync.
  3. 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

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


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/58ea32ed388cbee3. Report an issue: GitHub.