{"record":{"id":"59268e8c4d98a279","repo":"microsoft/semantic-kernel","slug":"application-is-already-stopped","errorCode":null,"errorMessage":"Application is already stopped.","messagePattern":"Application is already stopped\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Agents/Runtime/Core/AgentsApp.cs","lineNumber":70,"sourceCode":"    public async ValueTask StartAsync()\n    {\n        if (Interlocked.Exchange(ref this._runningCount, 1) != 0)\n        {\n            throw new InvalidOperationException(\"Application is already running.\");\n        }\n\n        await this.Host.StartAsync().ConfigureAwait(false);\n    }\n\n    /// <summary>\n    /// Shuts down the application by stopping the host.\n    /// Throws an exception if the application is not running.\n    /// </summary>\n    public async ValueTask ShutdownAsync()\n    {\n        if (Interlocked.Exchange(ref this._runningCount, 0) != 1)\n        {\n            throw new InvalidOperationException(\"Application is already stopped.\");\n        }\n\n        await this.Host.StopAsync().ConfigureAwait(false);\n    }\n\n    /// <summary>\n    /// Publishes a message to the specified topic.\n    /// If the application is not running, it starts the host first.\n    /// </summary>\n    /// <typeparam name=\"TMessage\">The type of the message being published.</typeparam>\n    /// <param name=\"message\">The message to publish.</param>\n    /// <param name=\"topic\">The topic to which the message will be published.</param>\n    /// <param name=\"messageId\">An optional unique identifier for the message.</param>\n    /// <param name=\"cancellationToken\">A token to cancel the operation if needed.</param>\n    public async ValueTask PublishMessageAsync<TMessage>(TMessage message, TopicId topic, string? messageId = null, CancellationToken cancellationToken = default)\n        where TMessage : notnull\n    {\n        if (Volatile.Read(ref this._runningCount) == 0)","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Agents/Runtime/Core/AgentsApp.cs#L52-L88","documentation":"AgentsApp.ShutdownAsync uses Interlocked.Exchange to flip _runningCount from 1 to 0; if it was not 1 (i.e. the app is not running) it throws InvalidOperationException. This prevents stopping a host that was never started or was already stopped.","triggerScenarios":"Calling ShutdownAsync without a prior StartAsync; calling ShutdownAsync twice; calling ShutdownAsync after PublishMessageAsync never actually transitioned the app to running (e.g. it threw).","commonSituations":"Cleanup/dispose handlers that shut down unconditionally even when startup failed; double shutdown in finally blocks across concurrent paths; tests reusing an app instance.","solutions":["Only call ShutdownAsync if StartAsync (or an auto-starting publish) succeeded.","Track started state yourself and skip shutdown when not running.","Catch and swallow InvalidOperationException in best-effort shutdown paths if appropriate."],"exampleFix":"// before\nawait app.StartAsync();\n// ... work ...\nawait app.ShutdownAsync();\nawait app.ShutdownAsync(); // throws\n\n// after\nawait app.StartAsync();\nbool started = true;\ntry { /* work */ }\nfinally { if (started) await app.ShutdownAsync(); }","handlingStrategy":"validation","validationCode":"bool started = false;\ntry { await app.StartAsync(); started = true; }\ncatch (InvalidOperationException) { /* was already running */ started = true; }\n// later:\nif (started) await app.ShutdownAsync();","typeGuard":null,"tryCatchPattern":"try { await app.ShutdownAsync(); }\ncatch (InvalidOperationException) { /* not running; nothing to stop */ }","preventionTips":["Only shut down when a prior successful start occurred.","Drive teardown from a single ownership path.","In best-effort cleanup, swallow the 'already stopped' exception."],"tags":["agentsapp","lifecycle","shutdown","runtime","dotnet"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}