#21020·ai

`@ai-sdk/mcp` 在 `invalid_client` 上清除预先注册的 OAuth 客户端,并在代码交换过程中掩盖错误

作者: JHawk0224创建于 2026年9月17日更新于 2026年9月17日
标签task-identify-issue-type-donetask-bug-reproduction-successfactory-activefactory-automatictask-identify-harness-labels-done

说明

Auth ()'将每一个无效的Client Error'/未经授权的Client Error'视为该DCR客户已死亡':它称为无效的Credititives ('all")'并用******的选项重复Auth Internal'。

对于** 事先登记的** 保密客户(客户信息()'已经返回一个静态的客户-id' /`客户-秘密')来说,这种追回是错误的。 SDK从未检查客户端是否动态注册. 在“授权代码”设定时,重试尤其被打破。

我们用这个对付雪花MCP 授权成功( Snowflake 发布了代码并重定向) 。 Token POST回QQ"error":"invalid client" QQ. ‘parseErrorResponse' 正确构建了‘invalidClientError'. 然后Auth()'删除了静态客户端,并重审了同样的回调。 Auth Internal'抛出:

交换授权代码时需要OAuth客户信息

打电话者从未见过`无效客户'。 他们看到一个未完成的召回失败。

资料来源: " packages/mcp/src/tool/oauth.ts " ( " auth " , " auth Internal " )。 同样的渔获量/重新捕获量在X@ai-sdk/[email protected]上,和X@ai-sdk/[email protected]上。

相关:#10062(预先注册的客户通过提供`客户信息() ' 得到支持,但这一恢复仍假定DCR)。

< 细节> < summary > 当前的代码 > auth () 回收 </ summary >

导出 async 函数 auth( 提供者, 选项) { 尝试{ 返回等待认证Internal( 提供者、 选项) 捕捉(反射){ 如果(则 无效的 ClientError 错误实例 错误实例 ) (中文(简体) ). 等待提供者. invalidate 证书?. ('all') 返回等待认证Internal( 提供者、 选项) {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? //. {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?


</详情>

预期行为

- 在**授权码交换** 期间,`无效客户 ' /`未经授权的客户 ' 应重新投放。 不擦去证书 。 不要重试相同的代码 。
- `验证证书(`所有')'不应为供应商已作为预先登记而提供的客户运行。 忘记`客户 id' /`客户 机密'只是对通过**新**认证(没有`授权代码 ' )签发的DCR客户的一种合理恢复,再试可以称为`注册客户()'。
- `无效的-赠予'-`无效的证书('tokens')'很好。

实际行为

1. 托肯端点返回`无效客户 ' 。
2. SDK删除客户身份、秘密、标志和核查人。
3. 在交换授权代码时,需要重试同一回调的 " 现有OAuth客户信息 " 。
4. 原OAuth错误已去.

在有静态客户端的**新鲜**`auth ()'(没有代码)上,相同的捕获量将删除预先登记的客户端并尝试DCR。

* 复制

`auth()'是回调路径:`serverUrl' +`授权代码',带有静态的`客户信息()'。

预期值:抛出“无效客户端” (“错误代码”:“无效客户端”)。 " 客户信息 " 不变。

实际:抛出`错误:交换时需要OAuth客户信息
. . . . . . .