{"record":{"id":"4da487b740836212","repo":"microsoft/autogen","slug":"subscription-already-exists","errorCode":null,"errorMessage":"Subscription already exists","messagePattern":"Subscription already exists","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-core/src/autogen_core/_runtime_impl_helpers.py","lineNumber":45,"sourceCode":"        await instance_getter(id)\n\n    return id\n\n\nclass SubscriptionManager:\n    def __init__(self) -> None:\n        self._subscriptions: List[Subscription] = []\n        self._seen_topics: Set[TopicId] = set()\n        self._subscribed_recipients: DefaultDict[TopicId, List[AgentId]] = defaultdict(list)\n\n    @property\n    def subscriptions(self) -> Sequence[Subscription]:\n        return self._subscriptions\n\n    async def add_subscription(self, subscription: Subscription) -> None:\n        # Check if the subscription already exists\n        if any(sub == subscription for sub in self._subscriptions):\n            raise ValueError(\"Subscription already exists\")\n\n        self._subscriptions.append(subscription)\n        self._rebuild_subscriptions(self._seen_topics)\n\n    async def remove_subscription(self, id: str) -> None:\n        # Check if the subscription exists\n        if not any(sub.id == id for sub in self._subscriptions):\n            raise ValueError(\"Subscription does not exist\")\n\n        def is_not_sub(x: Subscription) -> bool:\n            return x.id != id\n\n        self._subscriptions = list(filter(is_not_sub, self._subscriptions))\n\n        # Rebuild the subscriptions\n        self._rebuild_subscriptions(self._seen_topics)\n\n    async def get_subscribed_recipients(self, topic: TopicId) -> List[AgentId]:","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/_runtime_impl_helpers.py#L27-L63","documentation":"Raised by SubscriptionManager.add_subscription when an identical Subscription (matched via __eq__) is already registered with the runtime. The manager keeps a list of subscriptions and rejects exact duplicates to avoid delivering the same topic messages to an agent twice. It is a ValueError thrown synchronously inside the async add_subscription call.","triggerScenarios":"Calling runtime.add_subscription (or RuntimeAgentType registration that auto-adds class subscriptions) with a Subscription equal (source_topic_type, map/target, and id) to one already registered. Typical with TypeSubscription(agent_type=..., topic_type=...) added twice, e.g. once manually and once automatically by agent registration with skip_class_subscriptions left False.","commonSituations":"Registering the same agent type on two topics where DefaultSubscription/TypeSubscription overlap; adding a manual subscription for a topic the agent class already subscribes to via class-based subscriptions; retry logic that re-runs registration code without tracking prior success.","solutions":["Remove the existing subscription first: await runtime.remove_subscription(existing_sub.id), then add the new one","Pass skip_class_subscriptions=True when registering the agent if you intend to manage its subscriptions manually","Generate a unique subscription id (e.g. str(uuid.uuid4())) when you genuinely need two similar subscriptions that differ only in intent","Before adding, check any(s.id == new.id or s == new for s in runtime.subscription_manager.subscriptions)"],"exampleFix":"// before\nawait runtime.add_subscription(TypeSubscription(topic_type=\"tasks\", agent_type=\"worker\"))\n# ...later, same line again -> ValueError\n\n// after\nawait runtime.add_subscription(\n    TypeSubscription(id=str(uuid.uuid4()), topic_type=\"tasks\", agent_type=\"worker\")\n)","handlingStrategy":"validation","validationCode":"async def safe_add_subscription(runtime, new_sub):\n    from autogen_core import Subscription\n    existing = runtime.subscription_manager.subscriptions\n    if any(sub == new_sub or sub.id == new_sub.id for sub in existing):\n        return False  # already present\n    await runtime.add_subscription(new_sub)\n    return True","typeGuard":null,"tryCatchPattern":"try:\n    await runtime.add_subscription(sub)\nexcept ValueError as e:\n    if \"already exists\" in str(e):\n        logger.debug(\"subscription %s already registered\", sub.id)\n    else:\n        raise","preventionTips":["Pass skip_class_subscriptions=True when adding manual subscriptions for an agent type","Use unique uuid ids when intentionally creating parallel similar subscriptions","Keep one helper that owns all add_subscription calls so duplicates are structurally impossible"],"tags":["autogen-core","subscriptions","pubsub","duplicate","valueerror"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}