agentscope-ai/agentscope · error · ChannelError
Bot '{bot_id}' already registered as channel '{existing}'.
Error message
Bot '{bot_id}' already registered as channel '{existing}'. What it means
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.
Source
Thrown at src/agentscope/app/_service/_channel.py:77
Args:
user_id (`str`): Owner of the channel.
channel_type (`str`): Registered platform type id.
name (`str | None`): Optional display name.
credentials (`dict`): Platform credentials.
platform_config (`dict`): Platform behaviour options.
routing (`RoutingConfig`): Inbound routing rules.
session (`SessionSettings`): Derived-session settings.
enabled (`bool`): Whether to start the channel immediately.
"""
bot_id = self._types.extract_platform_bot_id(
channel_type,
credentials,
)
existing = await self._storage.get_channel_id_by_platform_bot_id(
bot_id,
)
if existing:
raise ChannelError(
f"Bot '{bot_id}' already registered as channel "
f"'{existing}'.",
409,
)
channel_id = _generate_id()
now = datetime.now()
record = ChannelRecord(
id=channel_id,
channel_type=channel_type,
name=name,
user_id=user_id,
enabled=enabled,
credentials=credentials,
platform_config=platform_config,
routing=routing,
session=session,
created_at=now,View on GitHub (pinned to e90f1c7592)
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
Example fix
// before
channel = await channel_service.create(platform="telegram", bot_id="123", ...)
# after
existing = await channel_service._storage.get_channel_id_by_platform_bot_id("123")
if existing:
channel = await channel_service._storage.get_channel(existing)
else:
channel = await channel_service.create(platform="telegram", bot_id="123", ...) Defensive patterns
Strategy: try-catch
Validate before calling
existing = await channel_client.get_channel_id_by_platform_bot_id(bot_id)
if existing is not None:
return existing # reuse, don't re-register
return await channel_client.create(platform=platform, bot_id=bot_id, ...) Try / catch
try:
channel = await channel_service.create(platform=p, bot_id=b, ...)
except ChannelError as e:
if e.status_code == 409:
channel = await channel_service.get_by_bot_id(b) # already registered
else:
raise Prevention
- Make registration scripts idempotent: check bot_id before create
- Disable submit buttons after the first click to avoid double registration
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- {str(e)}
- Channel '{channel_id}' not found.
- Team {team.id!r} has no resolvable leader; worker session {s
- {channel_cls.__name__} must set a non-empty 'channel_type' t
- Channel type '{channel_type}' is not registered; pass it to
AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28).
Data as JSON: /api/errors/810afe12190b40c9.
Report an issue: GitHub.