x_search 在 canonical xAI Auth Path 上因未解析的 SecretRef 而失败
回归问题导致当 xAI 凭证作为 exec SecretRef 存储在 canonical plugin-owned path 时,运行时快照无法解析,从而导致 x_search 失败。
🔍 症状
主要错误表现
当使用配置为 canonical 插件所有路径下的 exec SecretRef 的 xAI 凭据调用内置的 x_search 工具时,操作立即失败并返回以下错误响应:
{
"status": "error",
"tool": "x_search",
"error": "plugins.entries.xai.config.webSearch.apiKey: unresolved SecretRef \"exec:onepassword_xai:value\". Resolve this command against an active gateway runtime snapshot before reading it."
}CLI 复现步骤
# Attempt to invoke x_search via gateway CLI
$ clawctl tools invoke x_search --input '{"query": "latest OpenClaw release notes"}'
# Expected: Successful search response
# Actual: Error with unresolved SecretRef
{
"status": "error",
"tool": "x_search",
"error": "plugins.entries.xai.config.webSearch.apiKey: unresolved SecretRef \"exec:onepassword_xai:value\". Resolve this command against an active gateway runtime snapshot before reading it."
}配置上下文
使用以下配置结构时发生此故障(在同一基础设施上四月前验证正常工作):
{
"tools": {
"web": {
"search": {
"provider": "brave"
},
"x_search": {
"enabled": true,
"model": "grok-4-1-fast-non-reasoning",
"maxTurns": 2,
"timeoutSeconds": 30,
"cacheTtlMinutes": 15
}
}
},
"plugins": {
"entries": {
"xai": {
"config": {
"webSearch": {
"apiKey": {
"source": "exec",
"provider": "onepassword_xai",
"id": "value"
}
}
}
}
}
}
}环境详情
- OpenClaw 版本: 2026.4.10 (commit 44e5b62)
- 操作系统: macOS 25.3.0 (arm64)
- 安装方式: 全局 npm install / 本地 gateway 服务
- 安装类型: 通过 1Password provider 的 exec SecretRef
混淆观察
尽管存在以下情况,错误仍然持续出现:
web_search配置为使用braveprovider(非 xAI)- xAI 凭据存在于 canonical 插件所有路径
- 相同配置在四月 xAI 重构之前正常工作
🧠 根因分析
架构背景:四月 xAI 重构
此问题源于四月 2026 重构中引入的一系列破坏性变更:
- Issue #59674 — 将
x_search配置移至 xAI 插件边界之后,使其成为插件所有功能而非顶级工具。 - Issue #59691 — 使
x_search认证成为插件所有,要求凭据通过 xAI 插件的配置路径流动,而非直接工具配置。
根因:Exec Provider 的运行时快照过期问题
具体故障机制涉及网关运行时解析插件所有认证的 exec SecretRef 时的竞态条件或快照过期:
- 快照初始化: 网关启动时,会创建一个包含所有配置(包括 SecretRef)已解析值的运行时快照。
- Exec Provider 时序: Exec provider(如 1Password)需要执行外部命令来检索密钥。这些在快照创建期间进行解析。
- 初始化后访问:
x_search工具路径现在在工具执行期间访问plugins.entries.xai.config.webSearch.apiKey,而非初始快照创建期间。 - 过期引用: 如果自快照创建以来 exec provider 命令输出已更改(或者快照未正确填充插件所有路径),SecretRef 显示为未解析。
代码路径分析
故障发生在以下执行序列中:
x_search tool invocation
→ xAI plugin-owned auth path
→ plugins.entries.xai.config.webSearch.apiKey
→ SecretRef resolution check
→ Runtime snapshot lookup for "exec:onepassword_xai:value"
→ Result: UNRESOLVED (snapshot doesn't contain active value)为何这是回归问题
在四月重构之前:
x_search使用直接认证路径,无需插件所有凭据解析- Exec SecretRef 在工具调用时解析,而非快照依赖时间
- 相同的 1Password exec 命令正常工作,因为解析路径不穿越插件边界
四月之后:
x_search现在完全由插件所有- 认证解析针对网关运行时快照进行
- 当快照不包含当前解析值时,Exec SecretRef 被评估为"未解析"
相关问题
此回归问题与更广泛的运行时快照/SecretRef 解析问题相关:
- #50161 — 网关运行时中 SecretRef 处理未解析的通用问题
- #51263 — 动态 provider 的快照过期问题
- #57272 — Exec provider 缓存与新鲜解析问题
- #54555 — 缺失 xAI API 密钥检测(相关认证表面)
🛠️ 逐步修复
选项 A:使用静态 SecretRef(生产环境推荐)
用不需要运行时命令执行的静态引用替换 exec SecretRef:
{
"plugins": {
"entries": {
"xai": {
"config": {
"webSearch": {
"apiKey": {
"source": "static",
"value": "${XAI_API_KEY}"
}
}
}
}
}
}
}然后设置环境变量:
# Add to your shell profile or gateway environment
export XAI_API_KEY="xai-your-actual-api-key-here"
# Or inject at gateway startup
XAI_API_KEY="xai-your-actual-api-key-here" clawctl gateway start选项 B:内联静态值(仅限开发)
对于开发/测试,在配置中直接使用内联静态值:
{
"plugins": {
"entries": {
"xai": {
"config": {
"webSearch": {
"apiKey": {
"source": "inline",
"value": "xai-your-actual-api-key-here"
}
}
}
}
}
}
}选项 C:强制快照刷新(临时解决方案)
如果必须使用 exec provider,请强制网关快照刷新:
# Stop the gateway
clawctl gateway stop
# Clear the runtime snapshot cache
rm -rf ~/.config/openclaw/runtime/snapshots/
rm -rf ~/.local/share/openclaw/snapshots/
# Restart the gateway (this creates a fresh snapshot)
clawctl gateway start
# Verify snapshot is fresh
clawctl gateway status --verbose然后测试:
clawctl tools invoke x_search --input '{"query": "test"}'选项 D:迁移到原生密钥 Provider
如果使用 1Password,请迁移到不需要 exec 命令的原生 OpenClaw 1Password 集成:
{
"plugins": {
"entries": {
"xai": {
"config": {
"webSearch": {
"apiKey": {
"source": "onepassword",
"vault": "openclaw-secrets",
"item": "xai-api-key",
"field": "api_key"
}
}
}
}
}
}
}@openclaw/plugin-onepassword 并配置适当的 vault 访问权限。修复前 vs. 修复后配置
修复前(失败)
{
"plugins": {
"entries": {
"xai": {
"config": {
"webSearch": {
"apiKey": {
"source": "exec",
"provider": "onepassword_xai",
"id": "value"
}
}
}
}
}
}
}修复后(正常工作)
{
"plugins": {
"entries": {
"xai": {
"config": {
"webSearch": {
"apiKey": {
"source": "static",
"value": "${XAI_API_KEY}"
}
}
}
}
}
}
}🧪 验证
步骤 1:确认网关正在运行
$ clawctl gateway status
Gateway Status: RUNNING
Version: 2026.4.10 (44e5b62)
Runtime: Active
Snapshot: Valid (created: 2026-04-XX XX:XX:XX)步骤 2:验证 xAI 插件配置
$ clawctl config get plugins.entries.xai.config.webSearch.apiKey
{
"source": "static",
"value": "${XAI_API_KEY}"
}步骤 3:验证环境变量已设置
$ echo $XAI_API_KEY | head -c 10 && echo "..."
xai-sk-12...步骤 4:测试 x_search 工具调用
$ clawctl tools invoke x_search --input '{"query": "OpenClaw troubleshooting guide"}'
{
"status": "success",
"tool": "x_search",
"results": {
"query": "OpenClaw troubleshooting guide",
"results": [
{
"title": "OpenClaw Professional Troubleshooting Guide",
"url": "https://docs.openclaw.io/guides/troubleshooting",
"snippet": "..."
}
],
"model": "grok-4-1-fast-non-reasoning",
"tokensUsed": 142
}
}步骤 5:验证退出码
$ echo $?
0成功的 x_search 调用应返回退出码 0。
步骤 6:验证日志中无 SecretRef 错误
$ clawctl logs --tail 50 | grep -E "(x_search|SecretRef|xai)"
# Should show successful resolution, no unresolved errors:
[INFO] x_search: Tool invocation successful
[INFO] xai.plugin: Credential resolved successfully步骤 7:验证插件凭据解析
$ clawctl debug resolve-secret --path plugins.entries.xai.config.webSearch.apiKey
Resolved: true
Value Preview: xai-sk-12****
Source: static (env: XAI_API_KEY)
TTL: Persistent⚠️ 常见陷阱
1. 网关服务 vs. 用户 Shell 环境
问题: 在 shell 中设置的环境变量对网关服务守护进程不可用。
# This sets the variable for YOUR shell:
export XAI_API_KEY="xai-..."
# But the GATEWAY SERVICE runs in a different context:
# It won't see this variable unless configured system-wide解决方案: 为网关服务配置环境变量:
# For launchd (macOS)
# Edit /Library/LaunchDaemons/com.openclaw.gateway.plist
<key>EnvironmentVariables</key>
<dict>
<key>XAI_API_KEY</key>
<string>xai-...</string>
</dict>
# For systemd (Linux)
# Create /etc/systemd/system/openclaw-gateway.service.d/override.conf
[Service]
Environment="XAI_API_KEY=xai-..."2. 配置更改后快照未刷新
问题: 从 exec 更改为 static SecretRef 后,更改不会生效直到快照刷新。
解决方案:
# Always restart the gateway after config changes
clawctl gateway restart
# Or force snapshot refresh
clawctl gateway snapshot --refresh3. 插件未启用
问题: xAI 插件必须显式启用,插件所有的 x_search 才能正常工作。
解决方案:
# Verify xAI plugin is enabled
clawctl plugins list --enabled
# If not enabled:
clawctl plugins enable xai4. 版本不匹配
问题: 四月重构(x_search 插件所有)需要 OpenClaw 2026.4.0 或更高版本。
解决方案:
# Check current version
clawctl --version
# Update if needed
npm update -g @openclaw/cli
clawctl self-update5. Exec Provider 超时
问题: 如果 1Password CLI 花费时间过长,exec SecretRef 在快照创建期间会超时。
解决方案: 为 exec provider 添加超时配置:
{
"providers": {
"exec": {
"onepassword_xai": {
"command": "op read op://.../api_key/value",
"timeout": 10000
}
}
}
}6. macOS Gatekeeper/公证问题
问题: 在 macOS 上,1Password CLI (op) 可能被 Gatekeeper 阻止(如果未正确签名)。
解决方案:
# Verify op binary is allowed
xattr -l /usr/local/bin/op
# Should not show com.apple.quarantine
# If quarantined, remove:
xattr -d com.apple.quarantine /usr/local/bin/op7. Docker/容器环境变量
问题: 环境变量必须显式传递给容器。
解决方案:
# Pass env vars to Docker container
docker run -e XAI_API_KEY="xai-..." openclaw/gateway:latest
# Or use docker-compose.yml
environment:
- XAI_API_KEY=xai-...🔗 相关错误
- UNRESOLVED_SECRET_REF — 当 SecretRef 无法针对当前运行时快照解析时的通用错误。表现为:
unresolved SecretRef "exec:provider:id"。参见 issues #50161, #51263。 - MISSING_XAI_API_KEY — 表示 xAI 凭据在配置中完全不存在(无论格式如何)。即使凭据存在但不在 canonical 插件所有路径,也可能发生。参见 issue #54555。
- SNAPSHOT_STALE — 运行时快照包含过期值,需要刷新。通常与 SecretRef 解析失败一起出现。
- PLUGIN_NOT_INITIALIZED — xAI 插件尚未加载或启用。
x_search需要插件处于活动状态。 - EXEC_PROVIDER_TIMEOUT — exec SecretRef 的外部命令超过超时时间。
op(1Password CLI)命令可能很慢或被阻止。 - INVALID_SECRET_REF_FORMAT — SecretRef 不符合预期的
source:provider:id格式。 - GATEWAY_NOT_RUNNING — 当网关服务停止时无法调用工具。确保
clawctl gateway status显示RUNNING。
历史问题
| Issue | 标题 | 相关性 |
|---|---|---|
| #54555 | missing_xai_api_key even if filled in config | 相关 xAI 认证检测表面 |
| #59674 | moved x_search config behind the xAI plugin boundary | 回归的直接原因 |
| #59691 | made x_search auth plugin-owned | 回归的直接原因 |
| #50161 | General unresolved SecretRef handling | 根因类别 |
| #51263 | Snapshot staleness with dynamic providers | 根因类别 |
| #57272 | Exec provider caching vs. fresh resolution | 根因类别 |