{"record":{"id":"810afe12190b40c9","repo":"agentscope-ai/agentscope","slug":"bot-bot-id-already-registered-as-channel-exi","errorCode":null,"errorMessage":"Bot '{bot_id}' already registered as channel '{existing}'.","messagePattern":"Bot '(.+?)' already registered as channel '(.+?)'\\.","errorType":"error_code","errorClass":"ChannelError","httpStatus":409,"severity":"error","filePath":"src/agentscope/app/_service/_channel.py","lineNumber":77,"sourceCode":"        Args:\n            user_id (`str`): Owner of the channel.\n            channel_type (`str`): Registered platform type id.\n            name (`str | None`): Optional display name.\n            credentials (`dict`): Platform credentials.\n            platform_config (`dict`): Platform behaviour options.\n            routing (`RoutingConfig`): Inbound routing rules.\n            session (`SessionSettings`): Derived-session settings.\n            enabled (`bool`): Whether to start the channel immediately.\n        \"\"\"\n        bot_id = self._types.extract_platform_bot_id(\n            channel_type,\n            credentials,\n        )\n        existing = await self._storage.get_channel_id_by_platform_bot_id(\n            bot_id,\n        )\n        if existing:\n            raise ChannelError(\n                f\"Bot '{bot_id}' already registered as channel \"\n                f\"'{existing}'.\",\n                409,\n            )\n\n        channel_id = _generate_id()\n        now = datetime.now()\n        record = ChannelRecord(\n            id=channel_id,\n            channel_type=channel_type,\n            name=name,\n            user_id=user_id,\n            enabled=enabled,\n            credentials=credentials,\n            platform_config=platform_config,\n            routing=routing,\n            session=session,\n            created_at=now,","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/app/_service/_channel.py#L59-L95","documentation":"Raised by ChannelService.create when a channel with the same platform bot_id is already registered. The storage layer's get_channel_id_by_platform_bot_id returns the existing channel id, and the service refuses duplicate bot registration with ChannelError status 409 to keep the platform-bot-to-channel mapping unique.","triggerScenarios":"Calling create() twice with the same bot_id (e.g. reconnecting a Telegram/Slack bot, rerunning a setup script, or a retry after a timeout that actually succeeded server-side).","commonSituations":"Idempotency-less deployment scripts run twice; webhook re-registration after a pod restart; double-submit in the admin UI; retrying a create that failed client-side but succeeded server-side.","solutions":["Look up the existing channel first via get_channel_id_by_platform_bot_id and reuse it instead of creating a new one","Catch ChannelError with status 409 and treat it as success by fetching the existing channel","Make registration scripts idempotent by keying on bot_id before calling create","Remove the stale channel registration (delete) before re-creating if you intentionally want a fresh channel"],"exampleFix":"// before\nchannel = await channel_service.create(platform=\"telegram\", bot_id=\"123\", ...)\n# after\nexisting = await channel_service._storage.get_channel_id_by_platform_bot_id(\"123\")\nif existing:\n    channel = await channel_service._storage.get_channel(existing)\nelse:\n    channel = await channel_service.create(platform=\"telegram\", bot_id=\"123\", ...)","handlingStrategy":"try-catch","validationCode":"existing = await channel_client.get_channel_id_by_platform_bot_id(bot_id)\nif existing is not None:\n    return existing  # reuse, don't re-register\nreturn await channel_client.create(platform=platform, bot_id=bot_id, ...)","typeGuard":null,"tryCatchPattern":"try:\n    channel = await channel_service.create(platform=p, bot_id=b, ...)\nexcept ChannelError as e:\n    if e.status_code == 409:\n        channel = await channel_service.get_by_bot_id(b)  # already registered\n    else:\n        raise","preventionTips":["Make registration scripts idempotent: check bot_id before create","Disable submit buttons after the first click to avoid double registration"],"tags":["channel","duplicate","conflict-409","bot-registration"],"backgroundTag":"duplicate-resource-conflict","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}