{"record":{"id":"e3e3377c06118b06","repo":"python-telegram-bot/python-telegram-bot","slug":"either-contact-or-phone-number-and-first-name-must","errorCode":null,"errorMessage":"Either contact or phone_number and first_name must be passed as arguments.","messagePattern":"Either contact or phone_number and first_name must be passed as arguments\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/telegram/_bot.py","lineNumber":3587,"sourceCode":"                    |keyword_only_arg|\n            reply_to_message_id (:obj:`int`, optional): |reply_to_msg_id|\n                Mutually exclusive with :paramref:`reply_parameters`, which this is a convenience\n                parameter for\n\n                .. versionchanged:: 20.8\n                    Bot API 7.0 introduced :paramref:`reply_parameters` |rtm_aswr_deprecated|\n\n                .. versionchanged:: 21.0\n                    |keyword_only_arg|\n            contact (:class:`telegram.Contact`, optional): The contact to send.\n\n        Returns:\n            :class:`telegram.Message`: On success, the sent Message is returned.\n        \"\"\"\n        # The contact parameter is a convenience functionality added by us, so enforcing the\n        # mutual exclusivity here is nothing that Telegram would handle anyway\n        if (not contact) and (not all([phone_number, first_name])):\n            raise ValueError(\n                \"Either contact or phone_number and first_name must be passed as arguments.\"\n            )\n        if not bool(contact) ^ any([phone_number, first_name]):\n            raise ValueError(\n                \"Either contact or phone_number and first_name must be passed as arguments. \"\n                \"Not both.\"\n            )\n\n        if isinstance(contact, Contact):\n            phone_number = contact.phone_number\n            first_name = contact.first_name\n            last_name = contact.last_name\n            vcard = contact.vcard\n\n        data: JSONDict = {\n            \"chat_id\": chat_id,\n            \"phone_number\": phone_number,\n            \"first_name\": first_name,","sourceCodeStart":3569,"sourceCodeEnd":3605,"githubUrl":"https://github.com/python-telegram-bot/python-telegram-bot/blob/d3b69d2e9fb7af6c796f84516cfda751752c7cb7/src/telegram/_bot.py#L3569-L3605","documentation":"Raised by Bot.send_contact when neither a Contact object nor both phone_number and first_name are provided. The library enforces this client-side because at least one complete contact specification is required to build the Telegram API request.","triggerScenarios":"Calling send_contact(chat_id, contact=None) with no phone_number/first_name, or passing only phone_number without first_name (the all() check requires both).","commonSituations":"Forwarding contact data from user input where fields may be empty; building a contact from optional form fields where first_name is blank.","solutions":["Pass a telegram.Contact object: send_contact(chat_id, contact=Contact('+1555...', 'John'))","Or pass both phone_number and first_name as keyword arguments","Check that both strings are non-empty before calling when data comes from optional input"],"exampleFix":"// before\nawait bot.send_contact(chat_id=chat_id, phone_number='+15550100')\n// after\nawait bot.send_contact(chat_id=chat_id, phone_number='+15550100', first_name='John')","handlingStrategy":"validation","validationCode":"if contact is None and not (phone_number and first_name):\n    raise ValueError('need contact or phone_number+first_name')\nawait bot.send_contact(chat_id, contact=contact, phone_number=phone_number, first_name=first_name)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat phone_number/first_name as a pair: validate both before calling","Prefer passing a Contact object built once from validated data"],"tags":["telegram","bot","send-contact","argument-validation"],"backgroundTag":"missing-required-argument","analyzedSha":"d3b69d2e9fb7af6c796f84516cfda751752c7cb7","analyzedAt":"2026-08-28T16:18:54.805Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}