agentscope-ai/agentscope · error · ChannelError
Channel '{channel_id}' not found.
Error message
Channel '{channel_id}' not found. What it means
Thrown by ChannelService._require when storage.get_channel returns None for the given channel_id; it is the shared guard used by update and delete. It signals the channel id does not exist (never created or already removed) and surfaces as ChannelError with HTTP 404.
Source
Thrown at src/agentscope/app/_service/_channel.py:209
fields = await self._bus.registry_getall(
MessageBusKeys.channel_seen_chats(channel_id),
)
return sorted(fields.keys())
# -- internals --
async def _require(self, channel_id: str) -> ChannelRecord:
"""Load a channel record or raise a 404 ``ChannelError``.
Args:
channel_id (`str`): The channel to load.
Returns:
`ChannelRecord`: The record.
"""
record = await self._storage.get_channel(channel_id)
if record is None:
raise ChannelError(f"Channel '{channel_id}' not found.", 404)
return record
async def _notify(self, channel_id: str) -> None:
"""Publish a lifecycle notification (best-effort).
Args:
channel_id (`str`): The changed channel; reconcile re-reads
storage, so the payload is only a nudge.
"""
try:
await self._bus.publish(
MessageBusKeys.channel_lifecycle(),
{"channel_id": channel_id},
)
except Exception: # pylint: disable=broad-except
# Lost notifications are recovered by the periodic reconcile.
pass
View on GitHub (pinned to e90f1c7592)
Solutions
- Verify the channel still exists (list channels) before update/delete
- Treat 404 ChannelError in delete flows as already-deleted success when idempotency matters
- Refresh channel ids from the current environment instead of hardcoding them in configs
- Guard against double-submits in the UI by disabling the button after the first request
Example fix
# before
await channel_service.delete(channel_id="ch-old") # 404
# after
from ... import ChannelError
try:
await channel_service.delete(channel_id="ch-old")
except ChannelError as e:
if e.status_code != 404:
raise # already gone; treat as success Defensive patterns
Strategy: try-catch
Validate before calling
record = await channel_client.get_channel(channel_id)
if record is None:
raise ValueError(f"Channel {channel_id} does not exist")
await channel_client.update(channel_id, ...) Try / catch
try:
await channel_service.delete(channel_id)
except ChannelError as e:
if e.status_code == 404:
return # already deleted; idempotent success
raise Prevention
- Re-fetch channel lists before acting on ids cached in configs
- Treat delete-404 as success in idempotent workflows
When it happens
Trigger: Calling update(channel_id, ...) or delete(channel_id) with an id that was never registered, was deleted earlier, or came from a stale config/UI list.
Common situations: Deleting a channel twice (double click or retry after the first request succeeded); config files or environment variables holding a channel id from a previous environment; races where another admin removed the channel concurrently.
Related errors
- {str(e)}
- Bot '{bot_id}' already registered as channel '{existing}'.
- Agent {agent_id!r} not found.
- Session {session_id!r} not found for agent {agent_id!r}.
- {channel_cls.__name__} must set a non-empty 'channel_type' t
AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28).
Data as JSON: /api/errors/e354a6375bea0f14.
Report an issue: GitHub.