Roo Code 报 did not provide any assistant messages 怎么办?先分清是版本回归还是接入层
用 Roo Code 配 Gemini,持续报:
Unexpected API Response: The language model did not provide any assistant messages
对应 GitHub 上 RooCodeInc/Roo-Code 的 issue #6999(已关闭,27 条评论)。原报告环境是 Roo Code 3.25.11、Google Gemini、gemini-2.5-pro,复现步骤只有一句:调用 gemini-2.5-pro。
这类「空响应」报错在 Roo Code、Cline、Continue 这类自带密钥(BYOK)的工具上特别常见——因为链路比封闭产品多一层。这篇讲怎么快速定位是哪一层出的问题。
一、BYOK 工具的链路更长
用 Claude Code 或 Copilot 这种封闭产品时,链路基本是:你 → 产品 → 它自己的服务。
用 Roo Code 这类工具时,链路是:你 → 插件 → 你配的提供商 → 模型。
而「你配的提供商」这一环可能是:
- 模型厂商官方 API
- 中转/聚合服务
- 兼容 OpenAI 协议的第三方部署
- 本地跑的模型(vllm、ollama 之类)
多出来的这一层,就是多出来的故障点。 而报错通常只反映最外层的表象——「模型没给我任何回复」——它不会告诉你是模型没生成、还是中间层丢了、还是插件解析不了。
二、issue 里那条最有价值的线索
issue #6999 的评论区里,有一条观察特别值得注意:
我用的是 gpt-oss-120b 配 vllm,也遇到了同样的问题。但我注意到,一个我之前就打开着的会话(应该是在自动更新之前打开的)没有这个问题。而每一个新开的会话都不可用。 所以这可能是聊天模板的问题。我把 Roo 降级到 3.25.14,问题就消失了。因此我认为这是一次回归。
这段里有三条独立的、可操作的信息:
第一,旧会话正常、新会话全废。 这个对比极其有价值——它排除了「服务端出问题」和「模型不可用」。如果是服务端的问题,旧会话也一样会挂。同一时刻、同一个模型、同一个账号,旧的能用新的不能,那差别只可能在客户端构造请求的方式上。
第二,降级到 3.25.14 之后问题消失。 这直接指向版本回归。
第三,那位评论者用的是完全不同的模型和部署方式(gpt-oss-120b + vllm,而原报告是 gemini-2.5-pro)。跨模型、跨部署方式都复现,进一步说明问题在插件侧而不是某个提供商那边。
注意:这些都是社区观察,不是官方结论。 但这个推理链条是可以复用的。
三、一个能快速定位的对照实验
从上面那条线索能提炼出一套通用做法。撞上空响应时,按这个顺序做四个对照:
对照一:开一个新会话,和一个旧会话对比。
- 旧的能用、新的不能 → 指向客户端构造请求的方式(版本回归、模板变化)
- 都不能用 → 继续往下
对照二:换一个模型。
- 换了就好 → 那个模型或它的配额有问题
- 都不行 → 继续
对照三:换一个提供商。
比如你原来走中转服务,换成官方 API 直连(或者反过来)。
- 换了就好 → 问题在那个提供商/接入层
- 都不行 → 继续
对照四:降级插件版本。
- 降了就好 → 版本回归,等修复或者暂时留在旧版本
这四个对照的顺序是有讲究的:从最省事的(开个新会话)到最麻烦的(降级),而且每一步都能砍掉一大块可能性。
四、另一条:API Request Failed
同一个仓库的 issue #571(已关闭,35 条评论)是另一条高频的:
API Request Failed
具体报错内容是 Cannot read properties of undefined (reading '...')。原报告环境是 v3.3.2、OpenAI Compatible 提供商、Deepseek-V3/R1 模型。
Cannot read properties of undefined 是 JavaScript 的运行时错误——意思是代码想从一个东西里取属性,但那个东西是空的。放在这个场景里,意思是:插件拿到了一个它没预料到的响应结构,解析时崩了。
所以它跟本文主题是同一类:响应的形状不对。区别只是一个是「没有 assistant 消息」,一个是「结构里少了某个字段」。
评论区里有几条值得注意的信息:
- 有人用 GitHub 版的 Claude Sonnet 也遇到同样问题——跨提供商复现
- 有人说配 Deepseek 用了两天都正常,更新之后就一直卡在等待 API 响应——又一条指向版本的线索
- 关于提供商是直连还是中转的讨论——说明中转层是这类问题的常见嫌疑对象
这条 issue 里也没有官方定论。
五、还有一条:兼容层参数不匹配
同一个仓库里还有一条形态不同但同属「接入层」的:
400 Unsupported parameter: 'messages'.
出现在 Azure 上的 OpenAI 兼容部署(issue #6862,已关闭)。
这条的性质跟前面两条不同:它是明确的参数不被支持,而不是响应形状异常。「兼容 OpenAI 协议」不等于「完全一样」——不同的部署可能支持不同的参数集,插件按标准协议发的东西,那边可能不认。
撞上这类,方向是去看那个部署支持哪些参数,或者换一种接入方式。
六、BYOK 工具排查的几条经验
把这几条合起来,给用 Roo Code / Cline / Continue 这类工具的人几条实用建议:
记下你的完整链路。 插件版本 + 提供商 + 模型 + 接入方式。出问题时,这四样是你做对照实验的坐标。
新旧会话对比是最便宜的第一步。 几秒钟,能立刻区分「服务端问题」和「客户端问题」。
跨提供商复现 = 问题在插件侧。 如果换了完全不同的提供商还是同样的报错,就别在提供商那边耗了。
留意「更新之后开始的」。 BYOK 工具迭代快,回归不罕见。降级是这类工具里成功率相当高的一招,而且成本低。
中转和聚合服务是额外的嫌疑对象。 它们可能改写请求、可能对参数支持不全。排查时值得用官方直连做一次对照。
报错里出现 Cannot read properties of undefined 这类措辞时,那是程序内部的解析问题,不是你的配置写错了——别去反复改配置。
七、关于「是不是被限流了」的猜测
issue #6999 的评论区里还有一条猜测值得单独说,因为它代表了一类很常见的思路:
我开始觉得这跟便宜的、试用的或免费的模型被限流有关。他们节流你的请求,好优先服务付费用户。
这是用户猜测,没有任何证据支持,本文不采信。
但它值得拿出来说,是因为这类猜测在报错讨论区里非常普遍——当找不到解释时,人容易归因到「服务方在故意限制我」。 这种归因的问题在于:它无法验证,也无法据此行动。 你没法「解决」一个你猜出来的限流策略。
更实际的做法是回到可验证的层面:如果真是限流,通常会有明确的限流报错(429、rate limit exceeded 之类),而不是「没有返回任何 assistant 消息」。报错的形态本身就是证据——空响应和限流是两种不同的表现。
这也是本文强调对照实验的原因:猜测再多也不如一次对照来得快。 开个旧会话试试,几秒钟就知道方向对不对。
八、总结
- BYOK 工具的链路多一层,报错通常只反映最外层表象,需要靠对照实验定位。
- 最有价值的对照是新旧会话:旧会话能用、新会话不能,就排除了服务端问题,指向客户端构造请求的方式。
- 四步对照顺序:新旧会话 → 换模型 → 换提供商 → 降级版本。从省事到麻烦,每步砍掉一块可能性。
- 跨模型、跨提供商都复现 = 问题在插件侧。
- 社区在 issue #6999 里的经验是降级到 3.25.14 后问题消失,怀疑是版本回归——这是社区观察,官方未确认。
Cannot read properties of undefined是插件解析响应时崩了,不是你配置错了。- 「兼容 OpenAI 协议」不等于完全一样,参数支持范围可能不同。
本文引用的 issue 编号与内容来自 RooCodeInc/Roo-Code 仓库 issue #6999、#571、#6862 的公开评论,核对日 2026-08-08。均为社区经验,官方未在文档中确认。版本与产品行为会变化,以官方为准。