{"record":{"id":"e084ece3b2ae815e","repo":"microsoft/autogen","slug":"subscription-does-not-exist","errorCode":null,"errorMessage":"Subscription does not exist","messagePattern":"Subscription does not exist","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-core/src/autogen_core/_runtime_impl_helpers.py","lineNumber":53,"sourceCode":"        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]:\n        if topic not in self._seen_topics:\n            self._build_for_new_topic(topic)\n        return self._subscribed_recipients[topic]\n\n    # TODO: optimize this...\n    def _rebuild_subscriptions(self, topics: Set[TopicId]) -> None:\n        self._subscribed_recipients.clear()\n        for topic in topics:","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/_runtime_impl_helpers.py#L35-L71","documentation":"Raised by SubscriptionManager.remove_subscription when no registered subscription has the given id string. The manager scans self._subscriptions for a matching sub.id before filtering the list, so removing an unknown (or already-removed) id raises ValueError. This usually indicates a stale id, a subscription already cleaned up, or a typo in the id.","triggerScenarios":"Calling runtime.remove_subscription(id) with an id that was never added, was already removed, or whose form does not match (e.g. passing the subscription object or AgentType instead of its id string). Also happens when the runtime was recreated (fresh state) but a persisted id from a previous run is reused.","commonSituations":"Cleanup code that runs on every shutdown and is invoked twice; restoring state after a runtime restart while holding subscription ids from the old process; passing DefaultSubscription().id vs a custom id inconsistently.","solutions":["Check membership before removing: ids = [s.id for s in runtime.subscription_manager.subscriptions]; if target_id in ids: await runtime.remove_subscription(target_id)","Log the currently registered ids when the error occurs to see whether the id exists under a different form","Ensure remove-once semantics in shutdown hooks (e.g. a flag or try/except guarding repeated cleanup)"],"exampleFix":"# before\nawait runtime.remove_subscription(sub_id)  # ValueError if absent\n\n# after\nif any(s.id == sub_id for s in runtime.subscription_manager.subscriptions):\n    await runtime.remove_subscription(sub_id)\nelse:\n    logger.warning(\"subscription %s already removed\", sub_id)","handlingStrategy":"validation","validationCode":"async def safe_remove_subscription(runtime, sub_id: str) -> bool:\n    ids = [s.id for s in runtime.subscription_manager.subscriptions]\n    if sub_id not in ids:\n        return False\n    await runtime.remove_subscription(sub_id)\n    return True","typeGuard":null,"tryCatchPattern":"try:\n    await runtime.remove_subscription(sub_id)\nexcept ValueError as e:\n    if \"does not exist\" in str(e):\n        pass  # idempotent cleanup\n    else:\n        raise","preventionTips":["Make teardown run-once (flag or asyncio shielded cleanup task)","Store the Subscription objects (not just ids) returned/added and remove those exact ids","Log registered subscription ids at shutdown to detect double-cleanup"],"tags":["autogen-core","subscriptions","pubsub","cleanup","valueerror"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}