microsoft/autogen · error · InvalidOperationException
Invalid subscription id
Error message
Invalid subscription id
What it means
InvalidOperationException thrown by RegistryGrain.UnsubscribeAsync when request.Id cannot be parsed as a GUID. Subscription removal is keyed by the Guid issued at subscribe time, so a malformed id cannot be mapped to any stored subscription set.
Source
Thrown at dotnet/src/Microsoft.AutoGen/RuntimeGateway.Grpc/Services/Orleans/RegistryGrain.cs:229
throw new InvalidOperationException("Invalid subscription type");
}
// add the subscription by Guid
state.State.GuidSubscriptionsMap.TryGetValue(guid, out var existingSubscriptions);
if (existingSubscriptions is null)
{
existingSubscriptions = new HashSet<Subscription>();
state.State.GuidSubscriptionsMap[guid] = existingSubscriptions;
}
existingSubscriptions.Add(subscription.Subscription);
await state.WriteStateAsync().ConfigureAwait(false);
}
public async ValueTask UnsubscribeAsync(RemoveSubscriptionRequest request)
{
var guid = request.Id;
// does the guid parse?
if (!Guid.TryParse(guid, out var _))
{
throw new InvalidOperationException("Invalid subscription id");
}
if (state.State.GuidSubscriptionsMap.TryGetValue(guid, out var subscriptions))
{
foreach (var subscription in subscriptions)
{
switch (subscription.SubscriptionCase)
{
case Subscription.SubscriptionOneofCase.TypeSubscription:
{
// remove the topic from the set of topics for the agent type
state.State.AgentsToTopicsMap.TryGetValue(subscription.TypeSubscription.AgentType, out var topics);
topics?.Remove(subscription.TypeSubscription.TopicType);
// remove the agent type from the set of agent types for the topic
state.State.TopicToAgentTypesMap.TryGetValue(subscription.TypeSubscription.TopicType, out var agents);
agents?.Remove(subscription.TypeSubscription.AgentType);
break;
}View on GitHub (pinned to 027ecf0a37)
Solutions
- Use the exact Guid string returned when the subscription was created.
- Validate client-side before the call: Guid.TryParse(request.Id, out _) must succeed.
- Trim whitespace and strip quotes if the id traveled through JSON or query strings.
Example fix
// before
await registry.UnsubscribeAsync(new RemoveSubscriptionRequest { Id = "sub-42" });
// after
await registry.UnsubscribeAsync(new RemoveSubscriptionRequest { Id = subscriptionGuidString }); // e.g. "3f2504e0-4f89-11d3-9a0c-0305e82c3301" Defensive patterns
Strategy: validation
Validate before calling
if (!Guid.TryParse(request.Id?.Trim(), out var subscriptionGuid))
{
throw new ArgumentException($"'{request.Id}' is not a valid subscription id (GUID expected).");
} Type guard
static bool IsValidSubscriptionId(string? id) => Guid.TryParse(id?.Trim(), out _);
Try / catch
try { await registry.UnsubscribeAsync(request); }
catch (InvalidOperationException ex) when (ex.Message == "Invalid subscription id")
{
_logger.LogError("Unsubscribe called with non-GUID id '{Id}'; re-fetch subscriptions and retry.", request.Id);
} Prevention
- Store and reuse the exact Guid string returned by SubscribeAsync.
- Never synthesize subscription ids from names or counters.
- Validate with Guid.TryParse at the API boundary before hitting the grain.
When it happens
Trigger: Calling UnsubscribeAsync with an id that is not a GUID string — empty string, an int-generated identifier, a GUID with wrong formatting, or a prefix of the real id.
Common situations: Clients generating their own ids instead of using the one returned from SubscribeAsync; UI components passing a row index or name as the subscription id; whitespace or quotes around the id from JSON deserialization; copying only part of the id.
Related errors
- All agents must have a name.
- All agents must have a unique name.
- All agents in the workflow must be in the group chat.
- The from property of the message {message} is different from
- Invalid DataUri format, expected data:[<mediatype>][;base64]
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/d79f568f5500ee94.
Report an issue: GitHub.