Skip to content

[Bug] 移动远程控制陷入无限重配对死循环:每3-4秒整桥降级+重载工作区(remote.rpcFrame.replayBufferExceeded,空闲时也不停,任何会话均复现) #1257

Open

Description

@weiqianliu

问题类别 · Category

稳定性 / 崩溃 · Stability / Crash

涉及的 Agent 框架 · Agent framework

ZCode Agent(自研)

严重程度 · Severity

阻塞使用 · Blocking(大会话场景下手机端远程控制完全不可用;与 #973 同属中继回放机制,但触发条件、reasonCode 与表现均不同,非重复提交)

复现频率 · Reproducibility

必现 · Always(大会话下 100% 复现;今天单日桌面日志已记录 397 次 bridge degraded,bridgeGeneration 从 1 滚到 500+)


问题描述 · Description

移动远程控制(zcode.z.ai/remote)连接一个消息量较大的会话后,手机页面陷入无限重配对死循环:每 3~4 秒整桥降级 → 重新配对 → 重新加载工作区 → 约 4 秒后再次降级,循环不休。手机页面表现为周期性闪回「正在连接 <设备名> / 已配对,正在加载工作区…」加载页,无法正常浏览和操作。

桌面端日志实锤循环原因:

[warn] [web-remote-control] raw relay bridge degraded
       reasonCode: "remote.rpcFrame.replayBufferExceeded"   ← 注意与 #973 的 replayGraceExceeded 不同
[info] mobile diagnostic {"event":"recover-start","state":"paired",...}
[info] V2 device state {"state":"paired"}
[info] mobile diagnostic {"event":"state-transition","state":"paired","previousState":"authenticating"}
[info] attaching workspace bridge ... (重新加载工作区)
       ↑ 约 3~4 秒后再次 degraded,无限循环

关键实验数据(排除负载/网络/客户端内核因素)

  1. 挂载→降级间隔随会话增长单调缩短:上午约 5.5s → 下午缩至 2.5~3.8s(会话持续增长、页面 DOM 越来越大)。间隔高度恒定,呈确定性特征而非随机抖动。
  2. 静默实验:AI 侧完全停止输出、会话真空闲 90 秒,期间仍发生 34 次降级(间隔恒定 3.1~4.4s)。说明与会话流量无关,空闲时也死循环。
  3. 客户端无关:系统 WebView(Chromium 148.0.7778.120,内核很新)与 vivo 自带浏览器均复现;页面可见性 visibilityState:"visible"、online:true。
  4. 无用户操作触发:与 [Bug] 手机远程控制频繁报 fault.subscription.recoveryFailed:后台重连后中继帧回放超限 remote.rpcFrame.replayGraceExceeded,客户端不降级到快照重同步 #973 的「后台→前台」触发条件不同,本例页面全程前台静置即持续循环。

推断的机制

重放缓冲(replay buffer)容量按时间计约 4 秒;大会话的工作区全量加载耗时超过该窗口 → 缓冲在加载完成前必然溢出 → 降级 → 恢复动作又从零重新加载工作区 → 西西弗斯循环。会话越大,加载越慢,窗口相对越窄(与间隔缩短现象吻合)。一旦会话规模超过阈值,该会话在移动端即永久不可用。

复现步骤 · Steps to reproduce

  1. 桌面端 ZCode(macOS)开启「移动远程控制」,出现二维码;
  2. 手机扫码连接,登录同一账号;
  3. 打开一个消息量大的任务会话(本例:持续工作中数小时的重度会话,含大量流式消息与工具调用记录);
  4. 手机页面即开始每 3~4 秒闪回「正在连接 …/已配对,正在加载工作区…」加载页,无限循环;期间在会话里发消息/操作,页面稍纵即逝无法稳定操作;
  5. 桌面端日志持续出现 raw relay bridge degraded + remote.rpcFrame.replayBufferExceeded。

期望表现 · Expected behavior

  1. replayBufferExceeded 触发恢复时不应全量重配对+重载工作区,应降级为增量/快照重同步(与 [Bug] 手机远程控制频繁报 fault.subscription.recoveryFailed:后台重连后中继帧回放超限 remote.rpcFrame.replayGraceExceeded,客户端不降级到快照重同步 #973 的诉求一致:transport.resync({forceSnapshot: true}) 路径),让大会话也能在移动端恢复;
  2. 重放缓冲容量应与工作区加载耗时自适应(或溢出判定在恢复期间挂起),避免「加载永远跑不赢溢出窗口」的死循环;
  3. 恢复期间给移动端明确的状态提示(当前只闪加载页,用户无从得知是陷在循环里)。

实际表现 · Actual behavior

  • 手机页面每 3~4 秒闪回配对加载页,无限循环,大会话下基本不可用;
  • 桌面端 bridgeGeneration 无限递增(单日 500+),日志被 bridge degraded 刷屏(单日 397 次);
  • 会话空闲(无任何流式输出)时循环依旧,并非流量过载所致。

ZCode 版本 · ZCode version

3.16.3(macOS 桌面端)

设备 / 系统 / 浏览器 · Device / OS / Browser

  • 桌面端:macOS 15.6(Intel MacBook Pro 2019),ZCode Desktop 3.16.3
  • 手机端:vivo V2425A / Android 16 / 系统 WebView Chromium 148.0.7778.120(vivo 自带浏览器同样复现)

截图 / 录屏 / 日志 · Screenshots / Recordings / Logs

桌面端日志(~/.zcode/v2/logs/2026-10-27.log,SID 已部分脱敏;如需完整日志可提供):

[15:22:10.658] [warn] raw relay bridge degraded {"session":"d_Ufho…V4r","bridgeSessionId":"bridge-a3d2…","bridgeGeneration":48,"reasonCode":"remote.rpcFrame.replayBufferExceeded"}
[15:22:10.798] [info] mobile diagnostic {"event":"recover-start","state":"paired","visibilityState":"visible","online":true}
[15:22:11.078] [info] mobile diagnostic {"event":"state-transition","state":"paired","previousState":"authenticating"}
[15:22:11.193] [info] attaching workspace bridge … session=d_Ufho…V4r
[15:22:18.954] [warn] raw relay bridge degraded {… "bridgeGeneration":49, …}   ← 8 秒后再来一轮

挂载→降级间隔实测(python 对日志逐轮配对统计):

挂载时刻 降级时刻 间隔
15:28:25.566 15:28:29.324 3.8s
15:28:45.161 15:28:47.794 2.6s
15:28:58.269 15:29:01.453 3.2s
15:29:05.631 15:29:08.593 3.0s

(连续 13 轮 min=2.5s / max=3.8s / 平均=3.1s;会话空闲 90 秒窗口内仍发生 34 次)

相关 issue:#973(同属中继帧回放限制,reasonCode 为 replayGraceExceeded,由后台挂起触发、手动 Reconnect 可恢复;本 issue 为大会话前台静置下的 replayBufferExceeded 无限循环,无需任何触发操作)。

Activity

  1. github-actions commented on Oct 27, 2026

    @github-actions

    👋 感谢你的反馈,我们已经收到。

    • 维护者看到后会尽快回复你。
    • 状态保持为 status: 待评估,你可以随时补充信息。
    • 信息不全时我们会打上 needs: 更多信息 标签并 @ 你。

    👋 Thanks — we've received your issue.

    • A maintainer will get back to you as soon as we can.
    • Status stays at status: 待评估 (Triage); feel free to add context.
    • If we need more details, we'll add needs: 更多信息 and ping you.
  2. changed the title [-][Bug] 移动远程控制大会话陷入无限重配对死循环:每3-4秒整桥降级+重载工作区(remote.rpcFrame.replayBufferExceeded,空闲时也不停)[/-] [+][Bug] 移动远程控制陷入无限重配对死循环:每3-4秒整桥降级+重载工作区(remote.rpcFrame.replayBufferExceeded,空闲时也不停,任何会话均复现)[/+] on Oct 27, 2026
  3. weiqianliu commented on Oct 27, 2026

    @weiqianliu
    Author

    重要修正与会话无关的补充证据(2026-10-27 更新)

    OP 反馈与进一步实验表明:本 bug 与会话大小无关,任何会话(含新建会话)均复现。原报告将根因暂归为「大会话加载跑不赢溢出窗口」,此假设已被推翻,修正如下:

    1. 任何会话均复现:新建空会话同样每 3~4 秒循环刷新;
    2. 停止/开启远程控制不会更换会话:桌面端全天仅使用同一个 deviceSid(设置中持久化 webRemoteControlRelayV2Device.deviceSid),「停止→开启」复用同一 sid,无法通过重开会话获得干净状态;
    3. 桌面端设备状态机本身在高频翻动:日志显示 paired → waiting_terminal → connecting → token acquired → authenticating → paired → waiting_terminal → paired 每 ~5 秒一轮(16:09 多轮连续样本);
    4. 每次挂载都创建全新 bridge(bridgeSessionId 每次不同),仍确定性在 ~3 秒内溢出——排除「桥状态被污染」假设,指向挂载/消费/确认(ack)循环本身存在确定性缺陷;
    5. 静默实验补充:会话完全空闲(无任何流式输出)90 秒内仍发生 34 次降级,间隔恒定 3.1~4.4s——溢出与流量无关。

    当前疑点收敛

    每次 attach 后客户端的重放缓冲消费游标从未推进(否则不会恒定 3 秒溢出),但页面本身能收到数据并渲染(配对、聊天流一度可用)。怀疑方向:

    • 客户端 ack/消费确认帧未被桌面端记账(版本间协议不匹配?3.16.3 桌面端 ↔ 当前 zcode.z.ai 线上页面);
    • 或服务端 relay 对该 device session 的消费游标永久停留在 0(与服务端状态有关,换 sid 才能验证——但 UI 无法换 sid,需要 remote/device/delete 级别的重置)。

    建议官方优先验证:换一个全新 deviceSid(删除设备注册)后循环是否消失——可立刻区分「服务端会话状态坏死」与「客户端消费路径确定性缺陷」。

    环境补充:手机端 vivo V2425A / Android 16 / WebView Chromium 148;vivo 自带浏览器与系统 WebView 均复现;桌面端 macOS 15.6 Intel / 3.16.3。

  4. weiqianliu commented on Oct 27, 2026

    @weiqianliu
    Author

    最终实验:本地清除 deviceSid 无效,服务端原样归还同一 sid(2026-10-27 16:30 更新)

    OP 做了最彻底的本地重置实验:

    1. 完全退出 ZCode 桌面端(进程级确认退出);
    2. 退出后从 ~/.zcode/v2/setting.json 中删除持久化的 webRemoteControlRelayV2Device(含 deviceSid);
    3. 重启 ZCode → 重新开启「移动远程控制」→ 手机重新扫码。

    结果:服务端把同一个 deviceSid 原样发了回来(日志新挂载仍为 d_Ufho****,与旧 sid 前缀完全一致),循环 3 分钟内 26 次挂载 / 24 次降级,立刻原样复发。

    结论修正

    • deviceSid 是服务端按设备身份确定性分配的:仅清除本地持久化无法获得新会话,服务端记录(含其重放缓冲/消费游标状态)原样保留;
    • 因此「服务端单会话状态坏死」与「客户端协议缺陷」两个假设仍未分辨——分辨手段只剩 api/v1/remote/device/delete(即「切换设备」入口)或服务端手动清除该设备记录后重连;
    • 若官方(或用户通过「切换设备」)换得全新 deviceSid 后循环消失 → 是服务端会话状态坏死;若全新 sid 依旧循环 → 是当前 zcode.z.ai 线上控制页与桌面端桥(3.16.3)之间的确定性协议缺陷(线上页面始终为最新版本,桌面端协议若未同步更新即可解释「任何会话、任何客户端、任何负载全复现」)。

    用户侧现状

    • 手机端远程控制在当前状态下完全不可用(每 3~4 秒整页重载一次,无法停留);
    • 桌面端功能不受影响;
    • 无任何用户侧手段可恢复(UI 停止/开启、重启桌面端、清除本地持久化均已验证无效)。

    日志与脱敏样本可随时提供。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions