快速结论:这个报错通常发生在自建 LobeHub + Android 客户端(User-Agent `LobeHub-Mobile/android-v1.0.15`)中,当你在 Codex 会话里让已绑定的远程设备执行命令时,Android 没有走 Agent Gateway,而是回退到 Provider API,弹出 Codex API Key 提示或返回 InvalidProviderAPIKey。优先排查 Android 客户端上 `heterogeneousProvider` 与 `isGatewayMode` 是否为空或为 false。
适用环境:自建 LobeHub 服务端 2.2.14;Android 客户端 User-Agent `LobeHub-Mobile/android-v1.0.15`;macOS 桌面客户端 2.2.14;官方统一 Go Gateway 0.3.2;服务端设置 `ENABLE_AGENT_GATEWAY=1`;Agent Gateway 与 Device Gateway 使用独立公网域名,WSS/health/auth 检查均通过。Issue 未提供 Python、CUDA、显卡、PyTorch 等信息,不要据此推断。
最快修复方案:暂无确认的一步修复方案。Issue 中未给出官方补丁或已验证的一步配置修复;该问题被判定为 Android 客户端路由问题,桌面端对照测试证明服务端路由正确。可优先尝试的方向是确认 Agent 的 `agencyConfig.heterogeneousProvider` 是否已同步到 Android,以及 Android 运行时是否取到 `enableGatewayMode` / `agentGatewayUrl`,但这两点均属 Issue 中的推测性诊断,并非已验证修复。
注意事项:Issue 中所有可用证据都指向 Android 客户端的 dispatch 决策,而非 Gateway 连通性或服务端鉴权;不要在未验证的情况下修改 Gateway 域名、WSS 或鉴权配置。用于排查的日志可能包含 deviceId、账号与请求路径,注意脱敏。上述根因与诊断步骤均为 Issue 讨论中的推断,尚未被作者确认已修复。
问题场景
用户在自建 LobeHub 上从 Android 客户端登录,选择一个在线 macOS Gateway 设备,然后在 Codex 会话中要求它执行一条无害的终端命令并返回标记。预期 Android 与桌面端行为一致:通过所选设备创建远程 Agent operation,经 Agent Gateway 流式返回进度和最终结果。实际 Android 没有创建远程 operation,而是显示自定义 Codex API Key 提示 / InvalidProviderAPIKey。
服务端脱敏证据(一次复现,2026-08-26 09:16 UTC):
POST /trpc/mobile/aiChat.sendMessageInServer 200
POST /webapi/chat/codex 401
User-Agent: LobeHub-Mobile/android-v1.0.15
该次 Android 请求没有创建 Agent Gateway operation,失败的 assistant 消息被记录为 provider `codex`,说明原生客户端回退到了 Provider API 路径。
同一账号、模型、在线设备、服务端和提示词的 macOS 桌面端对照测试成功:
POST /trpc/lambda/aiAgent.execAgent 200
POST Device Gateway /api/device/agent/run 200
Agent Gateway operation: done
heteroIngest / heteroFinish: 200
桌面端正常流式返回工具调用和最终标记,reconnect/resume 也能取回已完成的 operation。Android 端设备列表与 device RPC 均可用,因此问题范围被缩小到 Android 的 Codex dispatch 路由,而不是 Gateway 连通性。
报错原文
[Bug] Android 1.0.15 routes remote Codex device execution to Provider API instead of Agent Gateway
POST /trpc/mobile/aiChat.sendMessageInServer 200
POST /webapi/chat/codex 401
User-Agent: LobeHub-Mobile/android-v1.0.15
InvalidProviderAPIKey
原因分析
Issue 讨论给出的判断是:这是 Android 客户端的路由问题,`selectRuntimeType()` 对 Codex agent 解析成了 `’client’` 而不是 `’gateway’`。服务端路由本身是正确的(桌面端对照测试已证明),问题完全出在 Android 客户端如何评估 dispatch 决策。
调度决策链路:`conversationLifecycle.ts` 中的 `sendMessage` 从 `this.#get().isGatewayModeEnabled(agentId)` 读取 `isGatewayMode`,并从 `agencyConfig` 解析 `heterogeneousProvider`,然后把它们传入 `selectRuntimeType()`。对于非 remote 的异构 provider(如 Codex),该函数会带着 `clientExecutionAvailable: isDesktop` 调用 `resolveExecutionTarget()`,除非目标解析为 `’local’`,否则返回 `’gateway’`。
关键回退分支:`heterogeneousProvider` 的解析为 `agencyConfig?.heterogeneousProvider ?? (isDesktop && !isGatewayMode && isHeterogeneousAgentModelId(…))`。在 Android 上 `isDesktop` 为 `false`,所以这个基于旧 model-id 的回退永远不会触发。如果 `agencyConfig.heterogeneousProvider` 也是 `undefined`(例如 agent 配置未正确同步到 Android 客户端),那么 `heterogeneousProvider` 就是 `undefined`,`selectRuntimeType` 会直接越过所有 hetero 检查。
此时如果 `isGatewayMode` 同样为假值——取决于 `isGatewayModeEnabled()` 能否从 `global_serverConfigStore` 读到 `serverConfig.enableGatewayMode`——函数就会返回 `’client’`。`’client’` runtime 会走 `aiChat.sendMessageInServer` → `/webapi/chat/codex`,而这条路径需要 Codex API Key,于是正好对上 `InvalidProviderAPIKey`。
`global_serverConfigStore` 是在 `createServerConfigStore` 里挂到 `window` 上的。如果 React Native 环境没有填充该 store(或没有从服务端配置中暴露 `enableGatewayMode` / `agentGatewayUrl`),`isGatewayModeEnabled()` 就会返回 `false`,从而阻断 Gateway 这条兜底路径。
需要注意的是,移动端 router 其实已经包含 `aiAgentRouter`(PR #14103 加入的 gateway 执行端点),也就是说服务端已经就绪,只是客户端从未走到该路径。
可能原因(Issue 讨论中列出的一项或两项):一是 `agencyConfig.heterogeneousProvider` 在 Android 上为 `undefined`,导致异构检测被整体跳过;二是 `isGatewayModeEnabled()` 在 Android 上返回 `false`,导致 Gateway 兜底从未激活。
环境排查
- 确认服务端 LobeHub 版本为 2.2.14,且已设置 `ENABLE_AGENT_GATEWAY=1`。
- 确认 Android 客户端 User-Agent 为 `LobeHub-Mobile/android-v1.0.15`(用于区分是否命中同一问题范围)。
- 确认官方统一 Go Gateway 版本为 0.3.2,Agent Gateway 与 Device Gateway 使用独立公网域名,且 WSS/health/auth 检查通过。
- 检查 agent 的数据库记录:`agencyConfig` 是否设置了 `heterogeneousProvider`,以及是否同时带有 `executionTarget: ‘device’` 和有效的 `boundDeviceId`;如果没有,桌面端可能只是把设备选择存在本地,而没有写入共享配置。
- 检查 Android 端 `config.getServerConfig` 拉取的配置是否包含 `enableGatewayMode` 与 `agentGatewayUrl`,这两项必须分别为 `true` 和非空,Gateway 路径才可能作为兜底激活。
- Issue 未提供 Python、CUDA、PyTorch、显卡等依赖信息,无需纳入排查范围。
解决步骤
- 先复现并抓取 Android 端日志,确认失败请求形态是否为 `POST /trpc/mobile/aiChat.sendMessageInServer 200` 后紧跟 `POST /webapi/chat/codex 401`,且 User-Agent 为 `LobeHub-Mobile/android-v1.0.15`。
- 对照同一账号、模型、在线设备、服务端和提示词,用 macOS 桌面客户端执行一次,确认是否得到 `POST /trpc/lambda/aiAgent.execAgent 200` 与 `POST Device Gateway /api/device/agent/run 200`。若桌面成功,即可把问题范围收敛到 Android 客户端。
- 检查 agent 的 DB 记录中 `agencyConfig` 是否设置了 `heterogeneousProvider`、`executionTarget: ‘device’` 和有效的 `boundDeviceId`。如果缺失,则在配置同步或持久化环节补齐(此步骤基于 Issue 的诊断建议,属可优先尝试方向)。
- 在 Android 端 `selectRuntimeType` 被调用的位置(约 conversationLifecycle.ts 第 409–420 行)记录 `heterogeneousProvider` 和 `isGatewayMode` 的实际取值,判断是哪一个输入为假。
- 若确认是 `isGatewayMode` 为假,检查 Android 应用通过 `config.getServerConfig` 获取的配置是否填充了 `enableGatewayMode` 和 `agentGatewayUrl`;这两项需为 `true` / 非空,Gateway 兜底才能生效。
- 不要把改动直接落到 Gateway 域名、WSS 或鉴权配置上:Issue 已确认设备列表、device RPC 与桌面端 Gateway 路径均正常,问题不在这里。
验证方法
在 Android 端重复相同操作(选择在线 macOS Gateway 设备,在 Codex 会话中执行无害命令并返回标记),确认不再出现 Codex API Key 提示或 InvalidProviderAPIKey;服务端日志中应出现 Agent Gateway operation 创建记录,并伴随 `heteroIngest` / `heteroFinish` 200,工具调用与最终标记能正常流式返回,reconnect/resume 也能取回已完成的 operation。若日志仍停留在 `/webapi/chat/codex 401`,说明 Android 仍走 Provider API 路径,问题未解决。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。

![[Bug] Claude Code heterogeneous agent fails with "spawn EINVAL" on Windows (npm install)](https://www.chat-gpts.plus/wp-content/uploads/2026/09/18493-b5d75f9f-768x403.jpg)
