microsoft/autogen · error · InvalidOperationException

Invalid subscription type

Error message

Invalid subscription type

What it means

InvalidOperationException thrown by RegistryGrain.SetSubscriptionAsync when a Subscription message's SubscriptionCase is neither TypeSubscription nor TypePrefixSubscription. The registry stores subscriptions in per-kind maps, so it must know which oneof case it received; an unset or unknown case hits the default arm.

Source

Thrown at dotnet/src/Microsoft.AutoGen/RuntimeGateway.Grpc/Services/Orleans/RegistryGrain.cs:211

                    if (topics is null)
                    {
                        topics = new HashSet<string>();
                        state.State.AgentsToTopicsMap[subscription.Subscription.TypeSubscription.AgentType] = topics;
                    }
                    topics.Add(subscription.Subscription.TypeSubscription.TopicType);

                    // add the agent type to the set of agent types for the topic
                    state.State.TopicToAgentTypesMap.TryGetValue(subscription.Subscription.TypeSubscription.TopicType, out var agents);
                    if (agents is null)
                    {
                        agents = new HashSet<string>();
                        state.State.TopicToAgentTypesMap[subscription.Subscription.TypeSubscription.TopicType] = agents;
                    }
                    agents.Add(subscription.Subscription.TypeSubscription.AgentType);
                    break;
                }
            default:
                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");

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Set exactly one oneof branch before subscribing: subscription.TypeSubscription = new TypeSubscription { TopicType = ..., AgentType = ... } or the TypePrefixSubscription equivalent.
  2. Guard client-side: throw early if request.Subscription.SubscriptionCase == SubscriptionOneofCase.None.
  3. Keep publishers and the gateway on proto definitions that agree on the subscription kinds.

Example fix

// before
var sub = new Subscription();
await registry.SetSubscriptionAsync(new SubscriptionRequest { Subscription = sub });

// after
var sub = new Subscription
{
    TypeSubscription = new TypeSubscription { TopicType = "events", AgentType = "MyAgent" }
};
await registry.SetSubscriptionAsync(new SubscriptionRequest { Subscription = sub });
Defensive patterns

Strategy: type-guard

Type guard

static bool IsValidSubscription(Subscription s) =>
    s.SubscriptionCase is Subscription.SubscriptionOneofCase.TypeSubscription
                     or Subscription.SubscriptionOneofCase.TypePrefixSubscription;

if (!IsValidSubscription(request.Subscription))
    throw new ArgumentException("Subscription must set TypeSubscription or TypePrefixSubscription");

Try / catch

try { await registry.SetSubscriptionAsync(request); }
catch (InvalidOperationException ex) when (ex.Message == "Invalid subscription type")
{
    _logger.LogError("Subscription payload missing oneof branch; rejecting request {Id}.", request.Id);
}

Prevention

When it happens

Trigger: Sending a SubscribeAsync request whose Subscription message has neither oneof branch set (constructing new Subscription {} and calling subscribe); adding a new SubscriptionOneofCase to the proto without updating this switch; forwarding a corrupt/uninitialized protobuf payload.

Common situations: Client code that builds Subscription imperatively and forgets to set TypeSubscription or TypePrefixSubscription; proto3 oneof semantics where assigning nothing leaves the case at None; SDK version skew introducing a third subscription kind the grain does not know.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/78783f4cb8483fc5. Report an issue: GitHub.