zai-org / zai-org/feedback

[Bug] 模型请求准备阶段(认证头刷新)的瞬时网络错误被硬编码为不可重试,长会话中途直接中断

Open
#732 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

priority: P2
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 后就停了,只能手动继续。

复现步骤

  1. 长会话多轮运行中
  2. 某轮 turn 开始时恰好遇到瞬时网络故障(代理切换、链路抖动等),故障点落在认证头刷新的请求上
  3. 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,并无条件覆盖为不可重试,底层的可重试分类被丢弃。

附加观察(顺带反馈)

  1. 错误弹窗里的 TraceID hydrate-trace 是客户端硬编码占位符(与 createInitialConversationSnapshot 相邻定义),并非服务端真实 trace ID。请求未到达服务端时用户拿到一个无法查询的假 ID,容易困惑,建议此时弹窗明确提示「请求未到达服务端、无服务端 trace」。
  2. 实测同一会话的下一轮 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.