microsoft/semantic-kernel · error · InvalidOperationException

Subscription with id {subscriptionId} does not exist.

Error message

Subscription with id {subscriptionId} does not exist.

What it means

RemoveSubscriptionAsync throws InvalidOperationException when subscriptionId is not present in the subscriptions dictionary. Removal is strict: you can only remove a subscription that was previously added and not yet removed.

Source

Thrown at dotnet/src/Agents/Runtime/InProcess/InProcessRuntime.cs:222

        {
            throw new InvalidOperationException($"Subscription with id {subscription.Id} already exists.");
        }

        this._subscriptions.Add(subscription.Id, subscription);

#if !NETCOREAPP
        return Task.CompletedTask.AsValueTask();
#else
        return ValueTask.CompletedTask;
#endif
    }

    /// <inheritdoc/>
    public ValueTask RemoveSubscriptionAsync(string subscriptionId)
    {
        if (!this._subscriptions.ContainsKey(subscriptionId))
        {
            throw new InvalidOperationException($"Subscription with id {subscriptionId} does not exist.");
        }

        this._subscriptions.Remove(subscriptionId);

#if !NETCOREAPP
        return Task.CompletedTask.AsValueTask();
#else
        return ValueTask.CompletedTask;
#endif
    }

    /// <inheritdoc/>
    public async ValueTask LoadStateAsync(JsonElement state)
    {
        foreach (JsonProperty agentIdStr in state.EnumerateObject())
        {
            AgentId agentId = AgentId.FromStr(agentIdStr.Name);

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Track which subscription IDs you actually added and only remove those.
  2. Make removal tolerant: check existence (or iterate _subscriptions via the public API) before calling RemoveSubscriptionAsync.
  3. Swallow InvalidOperationException in best-effort cleanup if a missing removal is acceptable.

Example fix

// before
await runtime.RemoveSubscriptionAsync(maybeStaleId); // throws if absent

// after
try { await runtime.RemoveSubscriptionAsync(maybeStaleId); }
catch (InvalidOperationException) { /* already removed */ }
Defensive patterns

Strategy: validation

Validate before calling

// Track added subscription ids and only remove known ones.
if (addedIds.Contains(subscriptionId))
{
    await runtime.RemoveSubscriptionAsync(subscriptionId);
    addedIds.Remove(subscriptionId);
}

Try / catch

try { await runtime.RemoveSubscriptionAsync(subscriptionId); }
catch (InvalidOperationException) { /* not present; nothing to remove */ }

Prevention

When it happens

Trigger: Removing an ID that was never added; removing an already-removed ID; a typo or mismatch in the ID string; attempting to remove during/after DisposeAsync drained state.

Common situations: Cleanup code referencing stale IDs; double-remove from concurrent teardown; ID obtained from a different runtime instance.

Related errors


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