aiogram 3.4.1机器人调用菜单触发TelegramBadRequest错误求助
Telegram机器人调用菜单触发BadRequest错误排查方案
问题描述
基于aiogram 3.4.1开发的Telegram机器人原本运行正常,搁置两个月后重新启用,调用任意菜单时触发如下错误:
aiogram.exceptions.TelegramBadRequest: Telegram server says - Bad Request: can't parse entities: Unsupported start tag "" at byte offset
同时伴随调度器错误栈:
Traceback (most recent call last): File "/Users/.../lib/python3.10/site-packages/aiogram/dispatcher/dispatcher.py", line 309, in _process_update response = await self.feed_update(bot, update, **kwargs) File "/Users/.../lib/python3.10/site-packages/aiogram/dispatcher/dispatcher.py", line 158, in feed_update response = await self.update.wrap_outer_middleware( File "/Users/.../lib/python3.10/site-packages/aiogram/dispatcher/middlewares/error.py", line 25, in __call__ return await handler(event, data) ... and more
已尝试更换aiogram版本、修改菜单项引号类型,均未解决问题,希望排查根源避免重写代码。相关代码片段如下:
main.py代码片段
from aiogram import Bot, Dispatcher from aiogram.enums import ParseMode from aiogram.fsm.storage.memory import MemoryStorage from aiogram.client.bot import DefaultBotProperties async def main() -> None: bot = Bot(API_TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML)) dp = Dispatcher(storage=MemoryStorage()) dp.include_router(common.router) await bot.delete_webhook(drop_pending_updates=True) await dp.start_polling(bot) if __name__ == "__main__": asyncio.run(main())
common.py代码片段
from aiogram import F, Router from aiogram.filters import Command from aiogram.fsm.context import FSMContext from aiogram.types import Message from handlers.keyboard import start_keyboard from handlers import add_hand from handlers import manage_hand from handlers import count_hand from handlers import service_hand from config import admins router = Router() router.include_router(add_hand.router) router.include_router(manage_hand.router) router.include_router(count_hand.router) router.include_router(service_hand.router) @router.message(F.from_user.id.in_(admins), Command(commands=["start"])) async def cmd(message: Message, state: FSMContext): await state.clear() keyboard=start_keyboard() await message.answer( text="Choose action", reply_markup=keyboard ) @router.message(Command(commands=["cancel"])) @router.message(F.text.lower() == "back") async def cmd(message: Message, state: FSMContext): await state.clear() keyboard=start_keyboard() await message.answer( text="Choose action", reply_markup=keyboard )
keyboard.py代码片段
from aiogram.types import ReplyKeyboardMarkup, KeyboardButton def make_row_keyboard(items: list[str]) -> ReplyKeyboardMarkup: row = [KeyboardButton(text=item) for item in items] return ReplyKeyboardMarkup(keyboard=[row], resize_keyboard=True) def start_keyboard(): kb = [ [ KeyboardButton(text="Add"), KeyboardButton(text='Manage'), KeyboardButton(text="Count"), KeyboardButton(text="Service") ], ] keyboard = ReplyKeyboardMarkup( keyboard=kb, resize_keyboard=True, input_field_placeholder="Choose action" ) return (keyboard)
问题根源与解决步骤
核心原因
错误本质是Telegram服务器无法解析消息中的HTML实体。你的机器人默认启用了ParseMode.HTML,搁置期间Telegram API对HTML解析的规则可能收紧,或是代码中存在未转义的HTML特殊字符/空标签(未在你贴出的代码中体现,大概率在其他路由模块)。
解决步骤
临时关闭HTML解析验证
修改main.py中的Bot初始化代码,将默认解析模式改为ParseMode.NONE,测试是否还报错:bot = Bot(API_TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.NONE))若恢复正常,说明问题确实出在HTML解析的实体处理上。
全面排查文本内容
检查所有发送消息的逻辑(包括未贴出的add_hand/manage_hand等模块),重点确认:- 键盘按钮文本、输入框提示语、消息内容中是否存在空HTML标签(如
<>) - 是否有未转义的HTML特殊字符(如
<、>、&,需转义为<、>、&)
- 键盘按钮文本、输入框提示语、消息内容中是否存在空HTML标签(如
显式指定解析模式
若需要保留HTML解析,可在发送消息时显式指定解析模式,覆盖默认设置,逐个模块排查问题点:await message.answer( text="Choose action", reply_markup=keyboard, parse_mode=ParseMode.NONE )锁定依赖版本
确保aiogram版本严格为3.4.1,避免自动升级带来的兼容性问题:pip install aiogram==3.4.1
内容的提问来源于stack exchange,提问作者Jahspear
相关产品推荐
相关产品推荐

