{"record":{"id":"4f5ad65a81a98589","repo":"agentscope-ai/agentscope","slug":"cannot-extract-platform-bot-id-for-type-channel","errorCode":null,"errorMessage":"Cannot extract platform_bot_id for type '{channel_type}'.","messagePattern":"Cannot extract platform_bot_id for type '(.+?)'\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/agentscope/app/channel/_registry.py","lineNumber":157,"sourceCode":"\n    def list_types(self) -> list[ChannelTypeSchema]:\n        \"\"\"List frontend schemas for all registered types.\"\"\"\n        return [self.schema_of(c) for c in self._classes.values()]\n\n    def extract_platform_bot_id(\n        self,\n        channel_type: str,\n        credentials: dict,\n    ) -> str:\n        \"\"\"Read the bot-identifying credential field, for uniqueness.\n\n        Args:\n            channel_type (`str`): The platform type id.\n            credentials (`dict`): Raw credentials to read the bot id from.\n        \"\"\"\n        channel_cls = self._classes.get(channel_type)\n        if channel_cls is None or not channel_cls.platform_bot_id_field:\n            raise ValueError(\n                f\"Cannot extract platform_bot_id for type '{channel_type}'.\",\n            )\n        bot_id = credentials.get(channel_cls.platform_bot_id_field)\n        if not bot_id:\n            raise ValueError(\n                f\"Missing '{channel_cls.platform_bot_id_field}' in \"\n                f\"credentials.\",\n            )\n        return str(bot_id)\n","sourceCodeStart":139,"sourceCodeEnd":167,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/app/channel/_registry.py#L139-L167","documentation":"ValueError raised by ChannelRegistry.extract_platform_bot_id when the given channel_type is not registered OR the registered class does not define a platform_bot_id_field. The method needs the class attribute to know which credential key holds the platform bot id; without it the bot id cannot be extracted from raw credentials.","triggerScenarios":"Calling extract_platform_bot_id (directly, or via channel CRUD handlers _to_response/create/update/delete that persist credentials) with an unregistered channel_type, or with a registered custom channel class that lacks a platform_bot_id_field class attribute.","commonSituations":"Custom channel implementations that forget platform_bot_id_field, channel classes registered for messaging but used in CRUD flows that require bot identity, unregistered type strings coming from user-submitted channel configs.","solutions":["If the type is unregistered, pass the class to create_app(channels=[...])","If it's your own channel class, set platform_bot_id_field (e.g. platform_bot_id_field = \"bot_id\") naming the credentials key that stores the bot id","Audit the channel_type value being sent in the API payload for typos"],"exampleFix":"# before\nclass MyChannel(ChannelBase):\n    channel_type = \"mychat\"\n    # no platform_bot_id_field\n\n# after\nclass MyChannel(ChannelBase):\n    channel_type = \"mychat\"\n    platform_bot_id_field = \"bot_id\"","handlingStrategy":"validation","validationCode":"cls = registry.get(channel_type)\nif cls is None or not getattr(cls, \"platform_bot_id_field\", None):\n    raise RuntimeError(f\"cannot extract bot id for {channel_type!r}; register the class and set platform_bot_id_field\")","typeGuard":"def supports_bot_id_extraction(registry, channel_type: str) -> bool:\n    cls = registry.get(channel_type)\n    return cls is not None and bool(cls.platform_bot_id_field)","tryCatchPattern":"try:\n    bot_id = registry.extract_platform_bot_id(t, creds)\nexcept ValueError as e:\n    if \"Cannot extract platform_bot_id\" in str(e):\n        return HTTPException(400, \"channel type unsupported for bot id extraction\")","preventionTips":["Set platform_bot_id_field on every custom channel class","Validate channel_type against the registry before calling credential helpers"],"tags":["channel","registry","credentials","bot-id"],"backgroundTag":"unregistered-service-type","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}