[Bug] 模型请求准备阶段(认证头刷新)的瞬时网络错误被硬编码为不可重试,长会话中途直接中断
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 22
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
基本信息
- 问题类别:对话 / Agent 交互(模型请求重试策略)
- Agent 框架:ZCode Agent(自研)
- 严重程度:影响体验
- 复现频率:偶现(网络抖动时必触发)
问题描述
模型请求的「准备阶段」(turn 开始时刷新运行时认证头)发生的瞬时网络错误被硬编码为不可重试。结果是同一次网络抖动:发生在流式请求阶段会自动重试并恢复,发生在认证头刷新阶段则直接中断整个 turn——长会话跑到一半弹 fetch failed 后就停了,只能手动继续。
复现步骤
- 长会话多轮运行中
- 某轮 turn 开始时恰好遇到瞬时网络故障(代理切换、链路抖动等),故障点落在认证头刷新的请求上
- UI 弹出
fetch failed(TraceID 显示为hydrate-trace),该轮 turn 直接终止,重试计数停在第 1 次尝试
期望表现
准备阶段的网络类错误(底层为连接失败、无 HTTP 状态码)至少做 1–2 次带退避的重试;或按底层错误分类放行——底层是网络错误就 retryable: true,与请求阶段的行为保持一致。
实际表现
第 1 次尝试即失败且不重试,整轮 turn 终止。日志证据(v3.12.3):
event: model.sdk.stream.failed statusMessage: "fetch failed"
attempt: 1 maxAttempts: 11 errorPhase: "prepare"
cause chain: AiSdkModelAdapterError
→ RuntimeHeadersRefreshError("fetch failed")
→ ProtocolRequestError("fetch failed")
客户端代码中的判定逻辑(minified 产物,变量名为 3.12.3 构建所对应):
- 错误分类函数
Ok()对请求阶段的网络连接失败(IPe(o)分支,消息为 "Network connection failed for the provider request")返回retryable: true; - 但尝试循环的 catch 中有一行硬编码:
w instanceof MU /* RuntimeHeadersRefreshError */ && (k.message = w.message, k.retryable = !1)—— 准备阶段抛出的任何异常都会被包装为RuntimeHeadersRefreshError,并无条件覆盖为不可重试,底层的可重试分类被丢弃。
附加观察(顺带反馈)
- 错误弹窗里的 TraceID
hydrate-trace是客户端硬编码占位符(与createInitialConversationSnapshot相邻定义),并非服务端真实 trace ID。请求未到达服务端时用户拿到一个无法查询的假 ID,容易困惑,建议此时弹窗明确提示「请求未到达服务端、无服务端 trace」。 - 实测同一会话的下一轮 turn 重新走准备阶段即成功,说明该类故障可自愈,属于典型的应重试场景。
环境
- ZCode Desktop v3.12.3(ProductVersion 3.12.3.7463)
- Windows 11 x64(build 10.0.26200)
- Provider:bigmodel coding-plan(GLM-5.3,Anthropic 兼容端点)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the client attempt loop that wraps RuntimeHeadersRefreshError and the Ok()/IPe(o) error classification described in the issue. Reproduce a prepare-phase network failure and verify that transient connection errors retry with backoff without discarding the underlying classification; also inspect the createInitialConversationSnapshot area if the trace-ID feedback is included.
Written by the indexing model from the issue text.
Assessment
- Domain
- desktop, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100