sessions_spawn 在生成隔离逻辑代理时失败,显示 'pairing required (1008)'
通过 sessions_spawn 生成的子代理因 WebSocket 1008 错误而失败,原因是网关将内部回环连接作为未授权的设备范围权限提升请求而拒绝。
🔍 症状
当尝试启动隔离的逻辑子代理时,sessions_spawn 命令会立即失败,无论运行时配置如何(acp、subagent 或 isolated)。
错误输出
$ openclaw sessions_spawn --agent my-agent --runtime acp -- "analyze this data"
Error: gateway closed (1008): pairing required
at WebSocket.<anonymous> (/path/to/node_modules/@openclaw/core/src/gateway/ws-client.js:142:15)
at WebSocket.emit (node:events:518:28)
at WebSocket.onClose (/path/to/node_modules/@openclaw/core/src/gateway/ws-client.js:89:12)
at SockJS.onClose (/path/to/node_modules/@openclaw/core/src/gateway/ws-client.js:56:14)
Session spawn failed: Connection rejected by gateway security policy
网关日志
[gateway] WARN [12:34:56.789] Incoming connection from loopback rejected: device pairing required
[gateway] WARN [12:34:56.790] Scope escalation request denied for device-id: internal-spawn-{uuid}
[gateway] INFO [12:34:56.791] Connection closed: code=1008, reason=pairing required
配置上下文
openclaw.json 中存在以下配置:
{
"acp": {
"allowedAgents": ["my-agent", "analysis-agent"]
}
}
行为表现
- 子代理启动在每次调用时都一致地失败
- 通过
openclaw devices approve进行手动设备审批无法解决问题 - 即使在针对
localhost或127.0.0.1生成代理时也会发生错误 - 主会话继续正常运行;仅生成的子代理受到影响
- 所有相关问题(#12210、#21445、#30740、#59428)表现出相同的错误代码和行为
🧠 根因分析
架构分析
OpenClaw v2026.4.12 中的 sessions_spawn 机制会从生成的子代理进程建立到网关的内部 WebSocket 连接。该连接通过环回接口(127.0.0.1),并受网关的设备配对强制执行层约束。
失败序列
- 启动发起:主会话调用
sessions_spawn,为目标代理创建一个新的隔离进程。 - 网关握手:子代理进程向
ws://localhost:{gateway-port}/acp发起 WebSocket 连接。 - 设备识别:网关的配对中间件为内部连接分配一个临时设备标识符:
internal-spawn-{uuid}。 - 范围升级阻止:生成的代理请求提升的权限范围(代理执行、会话管理),网关将其归类为需要配对设备。
- 1008 拒绝:网关使用 WebSocket 关闭代码 1008(
策略违规)终止连接,原因是"需要配对"。
技术根因
此回归问题源于 v2026.4.12 中的一项变更,该变更取消了对内部环回连接的隐式配对绕过。先前版本将 127.0.0.1 连接视为固有可信连接,自动授予 internal:spawn 权限。该更新统一了所有网络接口的配对强制执行,但无意中破坏了子代理启动路径。
网关配置未区分以下连接:
- 需要配对的外部设备连接(合法)
- 来自生成的子代理的内部环回连接
代码路径分析
// gateway/src/middleware/pairing-enforcer.ts (v2026.4.12)
function enforcePairing(ws, req) {
const remoteAddr = req.socket.remoteAddress;
// REMOVED: Legacy bypass for loopback
// if (remoteAddr === '127.0.0.1' || remoteAddr === '::1') {
// return next(); // Skip pairing check
// }
// Current: Unified enforcement (breaks internal spawns)
if (!isDevicePaired(req.headers['x-device-id'])) {
ws.close(1008, 'pairing required');
return;
}
}
配置缺口
acp.allowedAgents 设置控制哪些代理可以被调用,但不会为代理的内部网关连接授予配对豁免。这是两个正交的安全控制被错误地混为一谈。
🛠️ 逐步修复
选项 1:配置环回配对豁免(推荐)
在网关配置中添加显式环回配对豁免:
步骤 1: 找到或创建网关配置文件:
# Linux/macOS
~/.config/openclaw/gateway.json
# Windows
%APPDATA%\openclaw\gateway.json
# Docker container
/path/to/config/gateway.json
步骤 2: 添加 pairing 豁免设置:
{
"gateway": {
"port": 18789,
"pairing": {
"loopbackExempt": true,
"internalSpawnBypass": true
}
},
"security": {
"devicePairing": {
"requireForExternal": true,
"skipForLoopback": true
}
}
}
步骤 3: 重启网关:
# If running as a service
sudo systemctl restart openclaw-gateway
# Or if running directly
openclaw gateway stop
openclaw gateway start
选项 2:使用本地运行时而非 ACP
通过使用本地运行时来生成代理,完全避免 ACP 网关路径:
# Before (fails with 1008)
$ openclaw sessions_spawn --agent my-agent --runtime acp -- "task"
# After (uses isolated local runtime)
$ openclaw sessions_spawn --agent my-agent --runtime local -- "task"
选项 3:环境变量覆盖
在启动网关前设置 OPENCLAW_INTERNAL_SPAWN_BYPASS 环境变量:
# Add to shell profile or set inline
export OPENCLAW_INTERNAL_SPAWN_BYPASS=true
# Or start gateway with the variable
OPENCLAW_INTERNAL_SPAWN_BYPASS=true openclaw gateway start
选项 4:禁用配对强制执行(仅限开发环境)
对于开发环境,可完全禁用配对:
{
"gateway": {
"port": 18789,
"security": {
"enforcePairing": false
}
}
}
警告:此设置会禁用所有连接的配对,包括外部设备。请勿在生产环境中使用。
修复前与修复后配置对比
修复前(openclaw.json):
{
"acp": {
"allowedAgents": ["my-agent"]
}
}
修复后(gateway.json):
{
"acp": {
"allowedAgents": ["my-agent"]
},
"gateway": {
"port": 18789,
"pairing": {
"loopbackExempt": true,
"internalSpawnBypass": true
}
}
}
🧪 验证
应用修复后,使用以下步骤验证解决方案:
步骤 1:确认网关配置
$ openclaw gateway config show
预期输出应包含:
{
"pairing": {
"loopbackExempt": true,
"internalSpawnBypass": true
}
}
步骤 2:重启网关并检查日志
$ openclaw gateway restart
$ openclaw gateway logs --tail 20
预期日志条目:
[gateway] INFO [12:00:00.000] Gateway started on port 18789
[gateway] INFO [12:00:00.001] Loopback pairing exemption: enabled
[gateway] INFO [12:00:00.002] Internal spawn bypass: enabled
步骤 3:测试子代理生成
$ openclaw sessions_spawn --agent my-agent --runtime acp -- echo "test"
预期输出:
Spawning agent 'my-agent' with runtime 'acp'...
Agent spawned successfully in session sess_abc123
[sess_abc123] Executing task: echo test
test
[sess_abc123] Task completed. Exit code: 0
步骤 4:验证会话隔离
$ openclaw sessions list
预期输出应显示主会话和生成的子代理会话:
SESSION ID TYPE AGENT STATUS CREATED
sess_main primary - active 2026-04-12 10:00:00
sess_abc123 spawned my-agent active 2026-04-12 12:00:00
步骤 5:测试多代理编排
$ openclaw sessions_spawn --agent analysis-agent --runtime acp -- \
"analyze the quarterly data and generate a report"
预期:代理在无 1008 错误的情况下生成并开始执行任务。
验证退出代码
0:修复成功,子代理正确生成1008:修复未应用,配对强制执行仍然有效7:代理 ID 未在acp.allowedAgents中找到
⚠️ 常见陷阱
环境特定陷阱
- Docker 容器网络:在 Docker 中运行 OpenClaw 时,环回流量的路由方式可能不同。使用
host网络模式或在 docker-compose 中确保network=host:services: openclaw: network_mode: host - Windows WSL2:Windows 主机和 WSL2 之间的环回行为不同。网关可能在不同的接口上监听。使用以下命令验证:
netstat -tlnp | grep openclaw - macOS 沙盒:配置目录可能不同:
~/Library/Application Support/openclaw/
配置陷阱
- 配置文件位置错误:网关设置必须在
gateway.json中,而不是openclaw.json。后者处理代理权限;前者处理网关安全。 - 配置合并问题:如果同时使用环境变量和配置文件,环境变量优先。使用以下命令检查:
openclaw gateway config show --merged - 过时的网关进程:对
gateway.json的更改需要完全重启,而不仅仅是重新加载。验证进程是否实际已重启:ps aux | grep openclaw-gateway
身份验证陷阱
- 设备配对状态持久化:已批准的设备存储在本地。清除应用数据可能会使已批准的环回设备失效:
# Linux rm -rf ~/.local/share/openclaw/devices/*macOS
rm -rf ~/Library/Application\ Support/openclaw/devices/*
- 令牌过期:生成的子代理继承有效期有限的 auth 令牌。对于长时间运行的任务,请确保主会话保持活跃。
运行时选择陷阱
- 运行时不匹配:
--runtime acp通过 ACP 网关路由(受配对影响),而--runtime local完全绕过它。仅在代理逻辑不需要网关服务时使用local。 - 无效的代理 ID:
sessions_spawn中的代理 ID 必须与acp.allowedAgents中的条目完全匹配(区分大小写)。
已知回归问题
- 此问题首次出现在
v2026.4.12中,并在应用internalSpawnBypass配置之前持续存在于后续补丁版本中。 - 版本
v2026.4.11及更早版本不受影响,如果需要立即恢复功能,可作为降级路径使用。
🔗 相关错误
直接相关
- WebSocket 1008:策略违规
网关的配对强制执行关闭内部生成连接。这是阻止子代理生成的主要错误。 - 错误 #12210:"在全新安装时 'sessions_spawn' 失败,提示 'pairing required'"
v2026.4.x 系列中此回归模式的原始报告。 - 错误 #21445:"ACP 运行时子代理无法连接到网关"
跟踪 ACP 介导的生成的范围升级拒绝问题。 - 错误 #30740:"环回连接被错误标记为未配对设备"
记录将内部连接误分类为外部设备的问题。 - 错误 #59428:"尽管设置了 OPENCLAW_SKIP_PAIRING=true,但仍需要设备配对"
环境变量绕过对生成的子代理无效。
间接相关错误
- 错误 #45102:"对已批准代理返回退出代码 7 的 'sessions_spawn'"
在配对检查之前导致生成拒绝的配置不匹配。 - 错误 #33456:"长时间运行的生成上网关使用 1011 关闭连接"
在成功生成后发生的不相关错误,单独的超时问题。 - 错误 #77890:"主会话断开后子代理会话成为孤儿"
多代理工作流中的会话生命周期管理问题。
错误代码参考
| 代码 | 名称 | 上下文 |
|---|---|---|
| 1008 | Policy Violation | 配对强制执行阻止内部连接 |
| 1006 | Abnormal Closure | 生成握手期间网关崩溃 |
| 1011 | Unexpected Condition | 范围升级期间服务器端错误 |
| 7 | Invalid Agent | 代理 ID 不在 allowedAgents 列表中 |
| 65 | Session Limit | 超过最大并发会话数 |