OPENCLAW 2026
UPDATE_
WROTE_
WRONG_
NODE.

Абстрактное сравнение версий Node в терминале и launchd

До и после перехода на OpenClaw v2026.5.20 типовой инцидент, который маскируется под «ложное обновление» или «сломалась авторизация канала», на деле — рассинхрон абсолютного пути Node в LaunchAgent и which node в интерактивной оболочке. Команда openclaw update в follow-up цепочке берёт Node с текущего PATH, переписывает ai.openclaw.gateway, и следующий gateway restart падает с exit code 1. В 5.20 (PR #84043) цепочка обязана использовать managed service Node из plist; gateway status --json публикует runningVersion для отлова CLI/Gateway protocol skew. Ниже — матрица симптомов, таблица решений, шестишаговый Runbook, три ворота, кейс, пороги и FAQ. См. также: LaunchAgent и token, invalid config и doctor, HTTP/RPC timeout 5.2. Для 7×24 приёмки на удалённом Apple Silicon — контрольная плоскость MACGPU.

1. Разбор: не версия, а дрейф бинарника Node

1) Много Node на одном Mac — норма: Homebrew /opt/homebrew/opt/node/bin/node, nvm default 22.x, fnm global 20.x сосуществуют; openclaw gateway install запекает тогдашний абсолютный путь в plist. 2) PATH переключает реальность: после nvm use 25 вы запускаете openclaw update — старая логика гоняет post-install, doctor и restart через другой Node; package root не меняется, а service unit тихо указывает на иной глобальный npm-префикс. 3) Отличие от ложного обновления: там CLI 5.20, процесс Gateway 5.12; здесь бинарник и engines.node не сходятся — старт мгновенно падает или WS-handshake рвётся. 4) Protocol skew: 5.20 сохраняет health check при расхождении CLI/Gateway на один minor; если Gateway не поднимается из-за Node drift, вы видите unauthorized или RPC timeout, а не просто разные строки версии. 5) Наследие ai.openclaw.update.* (Issue #82167): updater LaunchAgent перезапускает job, шлёт SIGTERM шлюзу; с 5.20 update best-effort отключает legacy job — Runbook обязан включать launchctl list | grep openclaw.

2. Матрица решений: сначала Node или откат пакета?

Сигнал на местеПервое действиеЗапрет
openclaw --version и node в plist — разные majorЗаморозить PATH → update через service Node или gateway install --forceНе править ProgramArguments без бэкапа plist
gateway status --json без runningVersiongateway restart --wait, затем exit code launchdНе удалять ~/.openclaw целиком
После апдейта только Telegram отваливаетсяСначала исключить Node drift, потом слой каналовНе смешивать с HTTP timeout 5.2 в одном тикете
Ноутбук OK, удалённый Mac Studio — всё красноеDiff plist node vs npm root -g на каждой машинеНе копировать nvm-путь с ноутбука на прод
Нужен аудит измененийКонтрольный узел: шесть шагов + 30-минутный probeНе катить в пятницу без окна отката

3. Шестишаговый Runbook

Шаг 1 Заморозить «триаду» доказательств

Зафиксировать: openclaw --version, which node и node -v, первые два аргумента ProgramArguments в plist (путь к node + entry openclaw). Сохранить runningVersion из openclaw gateway status --json (5.20+).

Шаг 2 Разобрать порог engines.node

В каталоге глобального пакета openclaw открыть package.jsonengines.node (или release notes). Если major service Node ниже — сначала поднять Node для daemon, потом трогать пакет; иначе doctor зелёный, Gateway мёртв.

Шаг 3 Выровнять managed Gateway Node (путь 5.20)

На 2026.5.20 выполнить openclaw update: follow-up должен идти через baked node из LaunchAgent. При уже случившемся drift — openclaw gateway install --force с намеренным node, проверить совпадение npm root -g и plist.

Шаг 4 Очистить legacy updater LaunchAgent

launchctl list | grep openclaw: если ai.openclaw.update.* в цикле relaunch — на 5.20+ update отключит; на старых сборках вручную launchctl bootout gui/$UID/ai.openclaw.update.* (убедиться, что задача не in-flight). Issue #82167: «update OK, шлюз SIGTERM каждые 3 мин».

Шаг 5 Упорядоченный restart и JSON-зонд

openclaw gateway restart --force --wait, затем три раза подряд openclaw gateway status --json: runningVersion = целевой, RPC в SLA. На удалённом Mac: launchctl kick -k gui/$UID/ai.openclaw.gateway и повтор.

Шаг 6 Удалённая приёмка 7×24 и окно отката

На контрольном узле — чистый PATH без nvm switch, повтор шагов 1–5. Если прод всё ещё красный — pin версии, сохранить diff plist/npm prefix; closure только после 30 минут зелёного channels status --probe.

# Снимок триады openclaw --version which node && node -v plutil -p ~/Library/LaunchAgents/ai.openclaw.gateway.plist | head -20 openclaw gateway status --json # Префикс npm npm root -g ls -la "$(npm root -g)/openclaw/package.json" openclaw gateway install --force openclaw gateway restart --force --wait

4. Три ворота самопроверки

Ворота Node: путь в plist существует, node -v удовлетворяет engines.node. Ворота версии: runningVersion в JSON совпадает с openclaw --version в допустимом skew (5.20 health check покрывает один minor). Ворота каналов: openclaw channels status --probe без красного, за 30 минут нет «restart → мгновенный exit».

5. Кейс: «update успешен, утром Gateway offline на всех каналах»

«Ops на MacBook с nvm default 22; Mac Studio на Homebrew Node 25 держит Gateway 7×24. Пятница вечером — SSH и openclaw update, лог success. Суббота: plist node → /Users/ops/.nvm/.../node, прод зависит от /opt/homebrew/..., launchd exit 1 каждые 90 с.»

Команда сначала гоняла ложное обновление: CLI и status оба 5.20 — списали на token канала. Diff plist vs which node выявил Node drift. На контрольном MACGPU с единым Homebrew Node переустановили Gateway; на Studio — только замена первых двух ProgramArguments и gateway install --force. Восстановление за 30 минут. В change ticket: запрет openclaw update из shell с nvm на удалённый launchd-сервис; окно апдейта — service account или env -i с минимальным PATH.

6. Инсайт: pin рантайма Agent-шлюза на macOS

В 2026 экосистема Node (nvm/fnm/Volta/Homebrew) даёт две «истины»: глобальный CLI и daemon с абсолютными путями. OpenClaw 5.20 вшивает managed service Node в update chain — эксплуатация Agent-шлюзов переходит от «поставил и забыл» к pin, diff, rollback. Заказчики требуют в тикете: путь node в plist, скрин engines.node, JSON gateway status — не только строку версии.

На Windows/Linux много Node тоже бывает, но launchd на macOS жёстко семантичен к абсолютным путям — один drift и весь стек offline. Удалённый Apple Silicon с чистым PATH, снапшотом диска и воспроизводимыми логами — типовая золотая контрольная плоскость. Прогоните шесть шагов и 30-минутный probe на MACGPU, затем трогайте прод.

7. Числовые пороги для цитирования

① plist node ≠ which nodeапдейт не принят. ② engines.node требует Node ≥22 (по вашему package.json): service Node ниже — сначала runtime. ③ За 30 минут после апдейта launchd exit ≠0 более 3 раз — откат по умолчанию, plist diff в архив. ④ Три подряд gateway status --json без runningVersion — Unhealthy. ⑤ Разный глобальный npm-префикс локально и на удалённом Mac — запрет копировать фрагменты plist между машинами.

8. FAQ

Чем это отличается от ложного обновления? Там — строки версии; здесь — бинарник Node и путь в plist. Обязателен ли 5.20? С этой версии официальный fix drift; ниже — ручной gateway install --force. Docker? Обычно один Node в образе; следите за tag и volume. Ручной plist? Можно с бэкапом; предпочтительнее gateway install --force. Роль MACGPU? Контрольная приёмка, изоляция PATH, окно отката — не замена change approval.