fix: skip tool calls with None name/id to prevent crash and 400 error#8607
fix: skip tool calls with None name/id to prevent crash and 400 error#8607lingyun14beta wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces safety checks to skip tool calls with missing names, IDs, or function fields across several files, preventing errors when processing incomplete tool call responses. The reviewer noted that accessing parallel lists (self.tools_call_name and self.tools_call_ids) by index in astrbot/core/provider/entities.py could raise an IndexError if the lists are mismatched in length. They suggested refactoring this duplicated logic into a shared helper function to safely retrieve tool calls.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| for idx, tool_call_arg in enumerate(self.tools_call_args): | ||
| tool_name = self.tools_call_name[idx] | ||
| tool_id = self.tools_call_ids[idx] | ||
| if not tool_name or not tool_id: |
There was a problem hiding this comment.
Accessing self.tools_call_name and self.tools_call_ids by index idx can raise an IndexError if the parallel lists are mismatched in length. Since this similar logic is implemented in multiple places, refactor it into a shared helper function to avoid code duplication.
| for idx, tool_call_arg in enumerate(self.tools_call_args): | |
| tool_name = self.tools_call_name[idx] | |
| tool_id = self.tools_call_ids[idx] | |
| if not tool_name or not tool_id: | |
| for tool_id, tool_name, tool_call_arg in self._get_safe_tool_calls(): |
References
- When implementing similar functionality for different cases, refactor the logic into a shared helper function to avoid code duplication.
| for idx, tool_call_arg in enumerate(self.tools_call_args): | ||
| tool_name = self.tools_call_name[idx] | ||
| tool_id = self.tools_call_ids[idx] | ||
| if not tool_name or not tool_id: |
There was a problem hiding this comment.
Accessing self.tools_call_name and self.tools_call_ids by index idx can raise an IndexError if the parallel lists are mismatched in length. Since this similar logic is implemented in multiple places, refactor it into a shared helper function to avoid code duplication.
| for idx, tool_call_arg in enumerate(self.tools_call_args): | |
| tool_name = self.tools_call_name[idx] | |
| tool_id = self.tools_call_ids[idx] | |
| if not tool_name or not tool_id: | |
| for tool_id, tool_name, tool_call_arg in self._get_safe_tool_calls(): |
References
- When implementing similar functionality for different cases, refactor the logic into a shared helper function to avoid code duplication.
Fixes #8546 — 当 LLM 返回
function.name=None的工具调用时系统崩溃当使用 OpenAI 兼容接口代理 Claude 等模型时,中间层格式转换可能导致工具调用的
function.name或id字段丢失(变为None),引发连锁崩溃:entities.py中 Pydantic 校验失败:ValidationError: name must be a valid stringtool_use_id=None被写入对话历史,下一轮请求触发400: missing tool_use_idModifications / 改动点
astrbot/core/provider/sources/openai_source.py:解析工具调用时检查function、name、id是否为空,任一为空则跳过并打 warning;所有工具调用均被跳过时不设置role=tool,避免触发误报的EmptyModelOutputErrorastrbot/core/agent/runners/tool_loop_agent_runner.py:工具执行循环最开头检查name/id,为空则跳过整个条目(包括不产生tool_resultblock),防止tool_use_id=None写入对话历史astrbot/core/provider/entities.py:to_openai_tool_calls()和to_openai_to_calls_model()两个方法均加入 None guard,防止其他 provider source 漏过时触发 Pydantic 崩溃;同步修复旧方法to_openai_tool_calls()此前缺少 guard 的问题Screenshots or Test Results / 运行截图或测试结果
Checklist / 检查清单
😊 If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
/ 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。
👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
/ 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。
🤓 I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in
requirements.txtandpyproject.toml./ 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到
requirements.txt和pyproject.toml文件相应位置。😮 My changes do not introduce malicious code.
/ 我的更改没有引入恶意代码。
Summary by Sourcery
Handle malformed or incomplete tool calls more robustly to prevent crashes and invalid history entries when function name or id is missing.
Bug Fixes:
Enhancements: