背景
线上运行的 OpenClaw v2026.6.11 遇到两个严重问题:
- #99241 tool-result-placeholder:上下文累积到 65K tokens 后,工具输出被替换为
(see attached image)占位符,模型无法读取工具结果。触发阈值从最初的 180K 一路恶化到 65K,严重影响使用。 - #98416 reply-session-conflict:WebChat 连续发消息报
reply session initialization conflicted,会话不可用。
升级到 v2026.7.1-beta.2 后,#98416 官方已修复,#99241 靠 PR #98955(尾部 tool-result 保护)缓解。本文记录升级过程和补丁维护经验。
升级过程
- 备份:dist 目录 + openclaw.json 配置文件
- 升级:
npm install -g openclaw@2026.7.1-beta.2 - 重打补丁:6 个本地补丁重新打入(reply-session-source-fix 官方已修复,移除)
- patch-check:7/7 通过
- Gateway 重启,功能验证通过
备份位置:/usr/lib/node_modules/openclaw.bak-2026.6.11 + openclaw.json.bak-2026.6.11
补丁维护核心发现
1. attachment-normalize:遗漏的第二处栈溢出
6月25日打补丁时只修了第89行 data: URL 提取正则((.*)$ 对大字符串触发 V8 正则引擎栈溢出),改为 indexOf + slice。
但遗漏了第59行 isValidBase64 函数中的另一个正则:/^[A-Za-z0-9+/]+={0,2}$/.test(value),同样使用 + 量词对大字符串匹配,同样栈溢出。
之前测试的文件都是 6MB 左右,刚好没触发 V8 正则引擎的栈深度上限。7月10日上传 14MB 文件时暴露,改为逐字符 charCodeAt 遍历修复。
教训:补丁记录必须完整。一个函数里有两处正则栈溢出风险,只修一处是不够的。每次修复后要排查同文件中是否有同类问题。
2. reply-session-conflict:官方三层修复已到位
v2026.7.1-beta.2 中官方已完成三层修复:
- 源头修复(PR #98835):收窄 guard 对比范围到
sessionId/sessionFile身份字段,允许并发 metadata drift - 重入保护:
isActiveStoreWriter/runActiveStoreWriter正确处理reentrant: true - 重试退避:
retryDelays = [1000, 3000, 5000, 8000],maxRetries = 4
不再需要本地补丁。patches.json 中保留检测规则作为升级后的验证检查。
3. workspace-file-viewer:官方已修复
v2026.7.1-beta.2 的官方代码已包含 statWorkspacePath 非 touched 文件处理逻辑,前端 sessionKind 限制已移除。不需要本地补丁。
升级后测试时发现”补丁打了但没用”,实际是浏览器 JS 缓存问题,硬刷新后正常。前端代码变更后必须 Ctrl+Shift+R 硬刷新。
4. control-ui-allowed-folders:官方未修复,仍需本地补丁
问题 #10210240 分两层:
- 前端:正则
/^(\/Users\/[^/]+|\/home\/[^/]+)(?:\/|$)/只匹配 macOS 和 Linux 非 root 用户,不匹配/root。本地补丁加|\/root。 - 服务端:
getAgentScopedMediaLocalRoots只返回当前 agent 的 workspace,不包含其他 agent。本地补丁遍历cfg.agents.list追加所有 agent workspace。
升级后验证:发送 docx 文件到 WebChat,点击预览正常,不再提示 “Outside allowed folders”。
openclaw-patch-check 技能清理
升级过程中发现技能存在两个问题:
- 两套目录:
~/.openclaw/skills/openclaw-patch-check/(实际运行)和~/.openclaw/workspace/skills/openclaw-patch-check/(多余副本)。删除了 workspace 下的副本。 - 补丁记录过时:patches.json 从 7 个精简到 4 个,移除 3 个官方已修复的条目,更新检测规则。
当前 patches.json(4 个)
| ID | Issue | 类型 |
|---|---|---|
| attachment-normalize | #90098 两处正则栈溢出 | 本地补丁 |
| reply-session-conflict | #98416 reply session conflicted | 验证官方修复 |
| control-ui-allowed-folders-frontend | #10210240 前端正则缺 /root | 本地补丁 |
| control-ui-allowed-folders-backend | #10210240 服务端缺非默认 agent workspace | 本地补丁 |
架构限制:大文件上传
WebChat 通过 WebSocket 上传文件,MAX_PAYLOAD_BYTES = 25 * 1024 * 1024 硬编码限制。14MB 文件 base64 编码后约 19MB,可以上传。但超过 25MB 的文件 base64 后超过限制,无法上传。
已提交 Feature Request #103560,建议增加 HTTP multipart upload endpoint,不受 WS payload 限制。
补丁状态总览
| 补丁 | 状态 | 说明 |
|---|---|---|
| attachment-normalize | 本地补丁 | 两处正则栈溢出,PR #92223 未合并 |
| reply-session-conflict | 官方已修复 | v2026.7.1-beta.2 三层修复到位 |
| workspace-file-viewer | 官方已修复 | 代码已含 statWorkspacePath 逻辑 |
| control-ui-allowed-folders | 本地补丁 | 官方未修复 #10210240 |
| tool-result-placeholder | 已回滚 | PR #99756 打后更差,等官方根治 |
经验总结
- 补丁记录要完整:attachment-normalize 有两处正则栈溢出,只记一处导致遗漏。每处修改都要记录原始代码、修复代码、行号、原因。
- 检测规则要通用:从匹配特定文件名 hash 改为 glob
get-reply-*.js,从匹配特定数组值改为检测关键字retryDelays+maxRetries。 - 区分”补丁生效”和”官方已修复”:patches.json 中保留 reply-session-conflict 条目,作用从”检查本地补丁”变为”验证官方修复”。
- 前端变更后硬刷新:workspace-file-viewer 补丁打了但浏览器缓存旧 JS,硬刷新后正常。
- 维护单一数据源:发现两套技能目录后删除多余副本,只维护
~/.openclaw/skills/下的版本。
遗留问题
- #99241:beta.2 缓解但未根治,长上下文下仍可能触发 tool-result-placeholder
- #103560:Feature Request,HTTP 文件上传通道
- #90098:PR #92223 未合并,attachment-normalize 仍需本地补丁
- #10210240:control-ui-allowed-folders 官方未修复