{"record":{"id":"d79f568f5500ee94","repo":"microsoft/autogen","slug":"invalid-subscription-id","errorCode":null,"errorMessage":"Invalid subscription id","messagePattern":"Invalid subscription id","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Microsoft.AutoGen/RuntimeGateway.Grpc/Services/Orleans/RegistryGrain.cs","lineNumber":229,"sourceCode":"                throw new InvalidOperationException(\"Invalid subscription type\");\n        }\n        // add the subscription by Guid\n        state.State.GuidSubscriptionsMap.TryGetValue(guid, out var existingSubscriptions);\n        if (existingSubscriptions is null)\n        {\n            existingSubscriptions = new HashSet<Subscription>();\n            state.State.GuidSubscriptionsMap[guid] = existingSubscriptions;\n        }\n        existingSubscriptions.Add(subscription.Subscription);\n        await state.WriteStateAsync().ConfigureAwait(false);\n    }\n    public async ValueTask UnsubscribeAsync(RemoveSubscriptionRequest request)\n    {\n        var guid = request.Id;\n        // does the guid parse?\n        if (!Guid.TryParse(guid, out var _))\n        {\n            throw new InvalidOperationException(\"Invalid subscription id\");\n        }\n        if (state.State.GuidSubscriptionsMap.TryGetValue(guid, out var subscriptions))\n        {\n            foreach (var subscription in subscriptions)\n            {\n                switch (subscription.SubscriptionCase)\n                {\n                    case Subscription.SubscriptionOneofCase.TypeSubscription:\n                        {\n                            // remove the topic from the set of topics for the agent type\n                            state.State.AgentsToTopicsMap.TryGetValue(subscription.TypeSubscription.AgentType, out var topics);\n                            topics?.Remove(subscription.TypeSubscription.TopicType);\n\n                            // remove the agent type from the set of agent types for the topic\n                            state.State.TopicToAgentTypesMap.TryGetValue(subscription.TypeSubscription.TopicType, out var agents);\n                            agents?.Remove(subscription.TypeSubscription.AgentType);\n                            break;\n                        }","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/dotnet/src/Microsoft.AutoGen/RuntimeGateway.Grpc/Services/Orleans/RegistryGrain.cs#L211-L247","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait registry.UnsubscribeAsync(new RemoveSubscriptionRequest { Id = \"sub-42\" });\n\n// after\nawait registry.UnsubscribeAsync(new RemoveSubscriptionRequest { Id = subscriptionGuidString }); // e.g. \"3f2504e0-4f89-11d3-9a0c-0305e82c3301\"","handlingStrategy":"validation","validationCode":"if (!Guid.TryParse(request.Id?.Trim(), out var subscriptionGuid))\n{\n    throw new ArgumentException($\"'{request.Id}' is not a valid subscription id (GUID expected).\");\n}","typeGuard":"static bool IsValidSubscriptionId(string? id) => Guid.TryParse(id?.Trim(), out _);","tryCatchPattern":"try { await registry.UnsubscribeAsync(request); }\ncatch (InvalidOperationException ex) when (ex.Message == \"Invalid subscription id\")\n{\n    _logger.LogError(\"Unsubscribe called with non-GUID id '{Id}'; re-fetch subscriptions and retry.\", request.Id);\n}","preventionTips":["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."],"tags":["dotnet","orleans","validation","guid"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}