{"record":{"id":"9d6b6faa57d09c4c","repo":"agentscope-ai/agentscope","slug":"missing-channel-cls-platform-bot-id-field-in-c","errorCode":null,"errorMessage":"Missing '{channel_cls.platform_bot_id_field}' in credentials.","messagePattern":"Missing '(.+?)' in credentials\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/agentscope/app/channel/_registry.py","lineNumber":162,"sourceCode":"    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":144,"sourceCodeEnd":167,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/app/channel/_registry.py#L144-L167","documentation":"ValueError raised by ChannelRegistry.extract_platform_bot_id when the channel class is registered and has a platform_bot_id_field, but the provided credentials dict lacks that key or its value is empty/falsy. It means the stored/sent credentials are incomplete for identifying the bot on the platform.","triggerScenarios":"Creating or updating a channel via the API (create/update/delete -> extract_platform_bot_id) with a credentials payload missing the key named by platform_bot_id_field — e.g. sending {\"app_secret\": ...} for Feishu without \"app_id\"/bot id, or passing an empty string value.","commonSituations":"Partial credentials pasted from the platform console, env var for the bot id unset so it defaults to \"\", mismatch between the field name your code sends and the class's platform_bot_id_field (e.g. \"bot_id\" vs \"botId\").","solutions":["Include the exact key named by the channel's platform_bot_id_field with a non-empty value in the credentials dict","Check the env/secret source actually populates that key (no empty defaults)","Validate credentials client-side against the channel class before sending (see defense section)"],"exampleFix":"# before\ncredentials = {\"app_secret\": \"xxx\"}  # bot id key missing\nregistry.extract_platform_bot_id(\"feishu\", credentials)\n\n# after\ncredentials = {\"app_secret\": \"xxx\", \"app_id\": \"cli_a1b2c3\"}\nregistry.extract_platform_bot_id(\"feishu\", credentials)","handlingStrategy":"validation","validationCode":"field = registry.get(channel_type).platform_bot_id_field\nif not credentials.get(field):\n    raise ValueError(f\"credentials must include non-empty {field!r}\")","typeGuard":"def credentials_complete(registry, channel_type: str, credentials: dict) -> bool:\n    cls = registry.get(channel_type)\n    if cls is None:\n        return False\n    return bool(credentials.get(cls.platform_bot_id_field))","tryCatchPattern":"try:\n    bot_id = registry.extract_platform_bot_id(t, creds)\nexcept ValueError as e:\n    if \"Missing\" in str(e) and \"in credentials\" in str(e):\n        return HTTPException(422, detail=str(e))  # surface to API client","preventionTips":["Schema-validate credentials against the channel class before persisting","Log which field name the channel expects when onboarding a new platform"],"tags":["channel","credentials","bot-id","validation"],"backgroundTag":"missing-credential-field","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}