Gateway Management
The OpenClaw gateway is the central process that manages all sessions, crons, and channel connections. How you restart it, patch its config, and handle updates directly impacts uptime and session continuity.
Getting gateway management wrong is one of the fastest ways to cause an outage. The patterns here prevent the most common mistakes.
Restart Safety
Never restart via shell exec
# ❌ WRONG — conflicts with process manager lifecycle
exec("openclaw gateway restart")
# ✅ CORRECT — uses the gateway tool's managed restart path
gateway({ action: "restart" })If the gateway is managed by a process supervisor (launchd, systemd, Docker), restarting via CLI exec creates a race condition where both the supervisor and the CLI fight over process ownership. This can leave the gateway down for extended periods requiring manual recovery.
Always use the gateway tool with action: "restart" — it handles the restart through the proper channel (WebSocket signal to the running process).
Check for dynamic reload first
Many config changes take effect immediately via hot reload (SIGUSR1) without requiring a full restart. When the gateway logs:
config change applied (dynamic reads: tools.profile, ...)The change is already live. Do not follow up with a restart — it's redundant and risks downtime.
Pre-restart checkpoint
Gateway restarts kill all active sessions. Before any restart:
- Write current work state to
memory/wip.jsonwithactive: true - Include task description, current phase, and resume instructions
- Only then trigger the restart
- Use the gateway
noteparameter to deliver a resume message post-restart
Config Management
Use gateway tool, not direct file writes
# ❌ WRONG — bypasses validation and reload handling
exec("cat > ~/.openclaw/openclaw.json << EOF ...")
# ✅ CORRECT — validates config and handles reload
gateway({ action: "config.patch", ... })Direct file writes bypass config validation. Invalid config can prevent the gateway from starting, causing an outage that requires manual recovery.
config.patch gotchas
- Array fields replace, don't merge.
config.patchwithagents.listreplaces the entire array. You must include all existing agents, not just the new one. - Null values are silently ignored. Setting a field to
nullin a patch does not remove it. To remove a field, you may need to delete and recreate the containing object. - Secrets are stripped from responses.
config.applyreturns the config with tokens and secrets redacted. You cannot round-trip config through the gateway tool — the returned config is missing values.
Complex config changes
For changes that require array manipulation or secret preservation, direct file editing via jq may be necessary as a last resort. Always back up the config first:
cp ~/.openclaw/openclaw.json /tmp/openclaw-backup-$(date +%Y%m%d-%H%M).jsonUpdate Procedure
Before applying a major OpenClaw update with breaking changes:
- Audit affected areas — check release notes for breaking changes (delivery config, API changes, deprecated features)
- Check config schema — use
gateway({ action: "config.schema.lookup", path: "..." })to verify new field requirements - Apply the update —
gateway({ action: "update.run" }) - Run doctor —
openclaw doctor --fiximmediately after update to migrate legacy config - Verify health — confirm all crons, channels, and sessions are operational
Hotfix deployment
Local patches applied by copying only dist/ into the installed package directory are unsafe. The built output depends on the exact dependency graph at build time — a dist-only deploy into a different dependency tree can fail at runtime even when tests pass in the source repo.
For local hotfixes, use full package install (npm pack → npm install -g) or rebuild against the installed dependency tree.
Status
Hard-learned patterns. Every pattern here comes from a production outage or near-miss. Follow them strictly.