{"record":{"id":"30c199e5a41de9ee","repo":"python-telegram-bot/python-telegram-bot","slug":"message-and-chat-id-pair-are-mutually-exclusive","errorCode":null,"errorMessage":"Message and chat_id pair are mutually exclusive","messagePattern":"Message and chat_id pair are mutually exclusive","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/telegram/ext/_application.py","lineNumber":1572,"sourceCode":"            message (:class:`telegram.Message`, optional): A message with either\n                :attr:`~telegram.Message.migrate_from_chat_id` or\n                :attr:`~telegram.Message.migrate_to_chat_id`.\n                Mutually exclusive with passing :paramref:`old_chat_id` and\n                :paramref:`new_chat_id`.\n\n                .. seealso::\n                    :attr:`telegram.ext.filters.StatusUpdate.MIGRATE`\n\n            old_chat_id (:obj:`int`, optional): The old chat ID.\n                Mutually exclusive with passing :paramref:`message`\n            new_chat_id (:obj:`int`, optional): The new chat ID.\n                Mutually exclusive with passing :paramref:`message`\n\n        Raises:\n            ValueError: Raised if the input is invalid.\n        \"\"\"\n        if message and (old_chat_id or new_chat_id):\n            raise ValueError(\"Message and chat_id pair are mutually exclusive\")\n        if not any((message, old_chat_id, new_chat_id)):\n            raise ValueError(\"chat_id pair or message must be passed\")\n\n        if message:\n            if message.migrate_from_chat_id is None and message.migrate_to_chat_id is None:\n                raise ValueError(\n                    \"Invalid message instance. The message must have either \"\n                    \"`Message.migrate_from_chat_id` or `Message.migrate_to_chat_id`.\"\n                )\n\n            old_chat_id = message.migrate_from_chat_id or message.chat.id\n            new_chat_id = message.migrate_to_chat_id or message.chat.id\n\n        elif not (isinstance(old_chat_id, int) and isinstance(new_chat_id, int)):\n            raise ValueError(\"old_chat_id and new_chat_id must be integers\")\n\n        self._chat_data[new_chat_id] = self._chat_data[old_chat_id]\n        self.drop_chat_data(old_chat_id)","sourceCodeStart":1554,"sourceCodeEnd":1590,"githubUrl":"https://github.com/python-telegram-bot/python-telegram-bot/blob/d3b69d2e9fb7af6c796f84516cfda751752c7cb7/src/telegram/ext/_application.py#L1554-L1590","documentation":"Application.migrate_chat_data() accepts either a `message` (a service message about migration) or the `old_chat_id`/`new_chat_id` pair — not both. Passing message together with either chat id raises ValueError.","triggerScenarios":"`app.migrate_chat_data(message=msg, old_chat_id=-100, new_chat_id=-200)`; also message plus only one of the ids triggers it because the check is `message and (old_chat_id or new_chat_id)`.","commonSituations":"Custom on_chat_migration logic copying docs and filling every parameter; generic wrapper code that passes all kwargs through.","solutions":["Pass only `message` and let the ids be extracted from it","Or pass only the `old_chat_id`/`new_chat_id` pair without message"],"exampleFix":"# before\nawait app.migrate_chat_data(message=msg, old_chat_id=old, new_chat_id=new)\n\n# after\nawait app.migrate_chat_data(message=msg)","handlingStrategy":"validation","validationCode":"if message and (old_chat_id or new_chat_id):\n    raise ValueError('pass either message or the id pair, not both')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass either message or the id pair — never both","Avoid blanket kwargs forwarding into migrate_chat_data"],"tags":["validation","chat-migration","valueerror"],"backgroundTag":"conflicting-arguments","analyzedSha":"d3b69d2e9fb7af6c796f84516cfda751752c7cb7","analyzedAt":"2026-08-28T16:18:54.805Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}