API key 模式下每个 app-server 陷入 1Hz 认证重试死循环 #187

Closed
opened 2026-08-24 19:55:59 +08:00 by lhk229 · 2 comments
Owner

Issue 1(主):API key 模式下每个 app-server 陷入 1Hz 认证重试死循环

现象

每个 codex app-server 子进程,从启动到进程结束,每约 1.01 秒稳定输出一组三条日志:

INFO codex_login::auth::manager                             Reloading auth
INFO codex_login::auth::manager                             Reloaded auth, changed: false
INFO codex_app_server_transport::transport::remote_control::websocket
     waiting to resolve remote control preference until authentication is available
     error=remote control requires ChatGPT authentication

来源:login/src/auth/manager.rs:2319:2456app-server-transport/src/transport/remote_control/websocket.rs:609

没有退避,没有次数上限,进程活多久转多久。

根因

三个条件叠加,缺一不可:

1. API key 模式下隔离 home 里根本没有 auth.json

resolve_game_creator_codex_app_server_credentialcodex_app_server.rs:803)在 llm.apiKey 非空时返回 AppDataKey。而 prepare_isolated_game_creator_codex_home:979)只在 AuthBridge 分支写 auth.json:

let CodexAppServerCredential::AuthBridge { auth_json, .. } = credential else {
    return Ok(isolated_home);   // AppDataKey:直接返回空目录
};

所以 ChatGPT 登录态永远不会出现,重试条件永远不满足。

2. 全新 home 里没有已持久化的远程控制偏好

codex app-server 启动时无条件拉起 remote-control 子系统,第一步是解析已持久化的偏好。查残留 home 的 state_5.sqlite

remote_control_enrollments  ['websocket_url','account_id','app_server_client_name',
                             'server_id','environment_id','server_name',
                             'updated_at','remote_control_enabled']   rows= 0

空表 → 无偏好可读 → 必须回服务端解析。

3. 上游明确不支持 API key 解析该偏好

codex.exe 二进制内的字符串(app-server-transport/src/transport/remote_control/auth.rs 附近):

remote control requires ChatGPT authentication; API key auth is not supported

于是循环闭合:解析失败 → reload auth(重读那个不存在的 auth.json)→ changed: false → sleep ~1.01s → 重试。

同机 A/B

%TEMP% 下 31 个留有日志的残留隔离 home,按有无 auth.json 分组,循环记录数完全分离:

auth.json 存活(s) 一生写入记录数 记录/秒 home
False(API key) 44492 133188 2.99 IhSBiT
False 1171 3569 3.05 bZbMgc
False 1009 3089 3.06 QKqFpq
False 803 2477 3.08 3hzlRi
False 467 4124 8.83 SkutsH
False 399 3755 9.41 4KXLoi
False 161 2677 16.63 NmRQ0g
True(ChatGPT 桥接) 32 936 MQVawR
True 26 369 Y6Y3lA
True 20 243 Jxszmq
…其余 19 个 True ≤25 ≤407
  • 9 个 False home 全部命中循环22 个 True home 全部为 0 条
  • 空闲的 False home 稳定收敛到 2.99–3.08 记录/秒 —— 正好是"每 1.01 秒 3 条",说明这些进程除了这个循环什么也没干。
  • 有实际推理的 False home 速率更高(8.8–16.6),多出来的是 SSE trace。

一处需要说明的取证边界True 组的 home 全部存活 ≤32 秒,没有长命样本,所以无法直接证明"桥接模式下长期空闲也是 0"。但按 1.5 组/秒计,一个 32 秒窗口本应产生约 48 条循环记录,实测为 0 —— 这个缺失是有意义的。

影响

  • 单进程一生写入约 13.3 万条记录 / 约 23 MB 日志正文(codex 按行数裁剪,磁盘上只保留约 1050 条,所以文件本身不会无界增长)。
  • 每秒一次无谓的文件读 + 三次 sqlite 写,乘以并发进程数(见 Issue 2)。
  • 淹没了 codex 自己的诊断日志:真正有用的记录会被这个循环挤出保留窗口。

修复方向

目前没有落点可以关掉它:常规 ToolHost 连接压根不写 config.toml —— trust_isolated_game_creator_codex_workspace 只在 workspace_override.is_some() 时才调用(codex_app_server.rs:1192)。initialize 也只声明了 capabilities: { experimentalApi: true }:1328),没有涉及 remote control。

可考虑:给 AppDataKey 分支也写一份最小 config.toml,把 remote control 关掉(需先确认上游是否提供该开关;二进制里能看到 remote_control_enabled 落在 state DB,以及一份含 remote_control 的特性列表,值得先向上游确认配置路径)。顺带可以把日志级别按下来 —— 目前 game_creator_codex_cli_minimal_environmentcodex_cli.rs:316env_clear() 之后不传 RUST_LOG,用的是 codex 自己的默认档位(部分 target 默认 TRACE)。


## Issue 1(主):API key 模式下每个 app-server 陷入 1Hz 认证重试死循环 ### 现象 每个 codex app-server 子进程,从启动到进程结束,每约 1.01 秒稳定输出一组三条日志: ``` INFO codex_login::auth::manager Reloading auth INFO codex_login::auth::manager Reloaded auth, changed: false INFO codex_app_server_transport::transport::remote_control::websocket waiting to resolve remote control preference until authentication is available error=remote control requires ChatGPT authentication ``` 来源:`login/src/auth/manager.rs:2319`、`:2456`,`app-server-transport/src/transport/remote_control/websocket.rs:609`。 没有退避,没有次数上限,进程活多久转多久。 ### 根因 三个条件叠加,缺一不可: **1. API key 模式下隔离 home 里根本没有 auth.json** `resolve_game_creator_codex_app_server_credential`(`codex_app_server.rs:803`)在 `llm.apiKey` 非空时返回 `AppDataKey`。而 `prepare_isolated_game_creator_codex_home`(`:979`)只在 `AuthBridge` 分支写 auth.json: ```rust let CodexAppServerCredential::AuthBridge { auth_json, .. } = credential else { return Ok(isolated_home); // AppDataKey:直接返回空目录 }; ``` 所以 ChatGPT 登录态永远不会出现,重试条件永远不满足。 **2. 全新 home 里没有已持久化的远程控制偏好** codex app-server 启动时无条件拉起 remote-control 子系统,第一步是解析**已持久化的**偏好。查残留 home 的 `state_5.sqlite`: ``` remote_control_enrollments ['websocket_url','account_id','app_server_client_name', 'server_id','environment_id','server_name', 'updated_at','remote_control_enabled'] rows= 0 ``` 空表 → 无偏好可读 → 必须回服务端解析。 **3. 上游明确不支持 API key 解析该偏好** `codex.exe` 二进制内的字符串(`app-server-transport/src/transport/remote_control/auth.rs` 附近): > `remote control requires ChatGPT authentication; API key auth is not supported` 于是循环闭合:解析失败 → reload auth(重读那个不存在的 auth.json)→ `changed: false` → sleep ~1.01s → 重试。 ### 同机 A/B `%TEMP%` 下 31 个留有日志的残留隔离 home,按有无 `auth.json` 分组,循环记录数完全分离: | auth.json | 存活(s) | 一生写入记录数 | 记录/秒 | home | |---|---|---|---|---| | **False**(API key) | 44492 | 133188 | 2.99 | IhSBiT | | **False** | 1171 | 3569 | 3.05 | bZbMgc | | **False** | 1009 | 3089 | 3.06 | QKqFpq | | **False** | 803 | 2477 | 3.08 | 3hzlRi | | **False** | 467 | 4124 | 8.83 | SkutsH | | **False** | 399 | 3755 | 9.41 | 4KXLoi | | **False** | 161 | 2677 | 16.63 | NmRQ0g | | True(ChatGPT 桥接) | 32 | 936 | — | MQVawR | | True | 26 | 369 | — | Y6Y3lA | | True | 20 | 243 | — | Jxszmq | | …其余 19 个 True | ≤25 | ≤407 | — | — | - **9 个 `False` home 全部命中循环**;**22 个 `True` home 全部为 0 条**。 - 空闲的 `False` home 稳定收敛到 **2.99–3.08 记录/秒** —— 正好是"每 1.01 秒 3 条",说明这些进程除了这个循环什么也没干。 - 有实际推理的 `False` home 速率更高(8.8–16.6),多出来的是 SSE trace。 **一处需要说明的取证边界**:`True` 组的 home 全部存活 ≤32 秒,没有长命样本,所以无法直接证明"桥接模式下长期空闲也是 0"。但按 1.5 组/秒计,一个 32 秒窗口本应产生约 48 条循环记录,实测为 0 —— 这个缺失是有意义的。 ### 影响 - 单进程一生写入约 **13.3 万条**记录 / 约 **23 MB** 日志正文(codex 按行数裁剪,磁盘上只保留约 1050 条,所以文件本身不会无界增长)。 - 每秒一次无谓的文件读 + 三次 sqlite 写,乘以并发进程数(见 Issue 2)。 - 淹没了 codex 自己的诊断日志:真正有用的记录会被这个循环挤出保留窗口。 ### 修复方向 目前**没有落点**可以关掉它:常规 ToolHost 连接压根不写 `config.toml` —— `trust_isolated_game_creator_codex_workspace` 只在 `workspace_override.is_some()` 时才调用(`codex_app_server.rs:1192`)。`initialize` 也只声明了 `capabilities: { experimentalApi: true }`(`:1328`),没有涉及 remote control。 可考虑:给 `AppDataKey` 分支也写一份最小 `config.toml`,把 remote control 关掉(需先确认上游是否提供该开关;二进制里能看到 `remote_control_enabled` 落在 state DB,以及一份含 `remote_control` 的特性列表,值得先向上游确认配置路径)。顺带可以把日志级别按下来 —— 目前 `game_creator_codex_cli_minimal_environment`(`codex_cli.rs:316`)`env_clear()` 之后不传 `RUST_LOG`,用的是 codex 自己的默认档位(部分 target 默认 TRACE)。 ---
lhk229 changed title from Issue 1(主):API key 模式下每个 app-server 陷入 1Hz 认证重试死循环 to API key 模式下每个 app-server 陷入 1Hz 认证重试死循环 2026-08-24 19:56:05 +08:00
Member

修复已提交并由 PR #205 跟进:

  • 根因确认:API Key/provider-proxy 的隔离 CODEX_HOME 没有 ChatGPT auth.json,但 app-server 仍启动 remote-control,导致 desired_state=Unknown 时每约 1 秒认证重试。
  • 修复:握手完成后主动调用 remoteControl/disable;真实 AuthBridge 保持 remote-control;disable 失败则连接 fail-closed。
  • 日志:无 ChatGPT 登录态的子进程使用 RUST_LOG=warn,收敛预期认证噪音。
  • 回归:补充协议 fixture 与凭据策略测试,并修正文档。

验证已完成:Rust 定向测试 36 passed / 1 ignored / 0 failed,cargo check、AGC typecheck、编码检查、rustfmt 和 git diff --check 均通过。Windows 本机不编译 Unix-only fixture,Linux CI 仍需执行对应测试;真实模型 smoke 未运行以避免消耗模型调用。

PR:#205(修复 API Key app-server 认证重试循环)

修复已提交并由 PR #205 跟进: - 根因确认:API Key/provider-proxy 的隔离 CODEX_HOME 没有 ChatGPT auth.json,但 app-server 仍启动 remote-control,导致 desired_state=Unknown 时每约 1 秒认证重试。 - 修复:握手完成后主动调用 remoteControl/disable;真实 AuthBridge 保持 remote-control;disable 失败则连接 fail-closed。 - 日志:无 ChatGPT 登录态的子进程使用 RUST_LOG=warn,收敛预期认证噪音。 - 回归:补充协议 fixture 与凭据策略测试,并修正文档。 验证已完成:Rust 定向测试 36 passed / 1 ignored / 0 failed,cargo check、AGC typecheck、编码检查、rustfmt 和 git diff --check 均通过。Windows 本机不编译 Unix-only fixture,Linux CI 仍需执行对应测试;真实模型 smoke 未运行以避免消耗模型调用。 PR:#205(修复 API Key app-server 认证重试循环)
suzmii reopened this issue 2026-08-27 18:14:01 +08:00
Author
Owner

666

666
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: GenarrativeAI/Genarrative#187