Skip to content

[Bug]: commands.restart=false does not prevent gateway SIGUSR1 self-restart on config set (meta.lastTouchedAt) #5533

@hoohahaBIGHEAD

Description

@hoohahaBIGHEAD

Summary

commands.restart=false does not prevent the gateway from restarting.
A single openclaw config set updates meta.lastTouchedAt, which is treated as a restart-required key.
The gateway then self-restarts via SIGUSR1 even though restarts were supposed to be disabled.

Steps to reproduce

  1. Run the probe script that sets commands.restart=false, performs one config change, and prints only the new relevant log lines:
cat >/tmp/oc_probe.sh <<'SH'
set -e

OPENCLAW="/opt/homebrew/bin/openclaw"
LOGDIR="/tmp/openclaw"

pick_log() { ls -t "$LOGDIR"/openclaw-*.log 2>/dev/null | head -1; }

LOG_BEFORE="$(pick_log)"
[ -n "$LOG_BEFORE" ] || { echo "no log files in $LOGDIR"; exit 1; }

BASE_BEFORE="$(wc -l < "$LOG_BEFORE" | tr -d ' ')"
echo "LOG_BEFORE=$LOG_BEFORE"
echo "BASE_BEFORE=$BASE_BEFORE"

# Fix conditions
"$OPENCLAW" config set commands.restart false >/dev/null || true

# One config change only (no revert to avoid duplicate restarts)
"$OPENCLAW" config set agents.defaults.heartbeat.every "30m" >/dev/null
sleep 3

LOG_AFTER="$(pick_log)"
[ -n "$LOG_AFTER" ] || { echo "no log after change"; exit 1; }

if [ "$LOG_AFTER" = "$LOG_BEFORE" ]; then
  START=$((BASE_BEFORE+1))
else
  START=1
fi

echo "LOG_AFTER=$LOG_AFTER"
echo "START_LINE=$START"

NEW="$(sed -n "${START},\$p" "$LOG_AFTER" \
  | grep -E "gateway/reload|config change detected|requires gateway restart|signal SIGUSR1|received SIGUSR1" \
  | tail -n 200 || true)"

echo "$NEW"

SIGUSR1="$(echo "$NEW" | grep -c "SIGUSR1" || true)"
KEYS="$(echo "$NEW" | sed -n 's/.*requires gateway restart (\(.*\)).*/\1/p' | tail -n 1)"

if [ "$SIGUSR1" -gt 0 ]; then
  echo "SUMMARY: SIGUSR1=YES restart_keys=${KEYS:-unknown}"
else
  echo "SUMMARY: SIGUSR1=NO restart_keys=${KEYS:-none}"
fi
SH

bash /tmp/oc_probe.sh
  1. Confirm the config file metadata changes (shows meta.lastTouchedAt updated by a config set):
CFG="$HOME/.openclaw/openclaw.json"
cp "$CFG" /tmp/oc_before.json

/opt/homebrew/bin/openclaw config set agents.defaults.heartbeat.every "30m" >/dev/null
sleep 1

cp "$CFG" /tmp/oc_after.json
diff -u /tmp/oc_before.json /tmp/oc_after.json | sed -n '1,200p'
  1. Observe the printed summary and log lines from step (1).

Expected behavior

When commands.restart=false, config changes that “require restart” should not automatically restart the gateway.
The CLI can still say “Restart the gateway to apply.”, but the gateway should not self-restart unless explicitly requested.

Actual behavior

The gateway restarts automatically anyway.
The logs show requires gateway restart (meta.lastTouchedAt) followed by signal SIGUSR1 received and received SIGUSR1; restarting.
The probe output ends with:

SUMMARY: SIGUSR1=YES restart_keys=meta.lastTouchedAt

Also, the config file diff shows only metadata changed, e.g.:

 "meta": {
   "lastTouchedVersion": "2026.1.29",
-  "lastTouchedAt": "2026-01-31T15:36:29.310Z"
+  "lastTouchedAt": "2026-01-31T15:38:07.076Z"
 },

Environment

  • Clawdbot version: 2026.1.29 (commit a5b4d22 shown by CLI banner)
  • OS: macOS (Darwin 24.3.0, arm64)
  • Install method (pnpm/npx/docker/etc): npm (Homebrew path: /opt/homebrew/bin/openclaw)

Logs or screenshots

Probe output excerpt (from bash /tmp/oc_probe.sh):

LOG_BEFORE=/tmp/openclaw/openclaw-2026-01-31.log
BASE_BEFORE=1942
LOG_AFTER=/tmp/openclaw/openclaw-2026-01-31.log
START_LINE=1943
{"0":"{\"subsystem\":\"gateway/reload\"}","1":"config change detected; evaluating reload (meta.lastTouchedAt, agents.defaults.heartbeat.every, agents.defaults.contextPruning)", ...}
{"0":"{\"subsystem\":\"gateway/reload\"}","1":"config change requires gateway restart (meta.lastTouchedAt)", ...}
{"0":"{\"subsystem\":\"gateway\"}","1":"signal SIGUSR1 received", ...}
{"0":"{\"subsystem\":\"gateway\"}","1":"received SIGUSR1; restarting", ...}
SUMMARY: SIGUSR1=YES restart_keys=meta.lastTouchedAt

Config diff excerpt (from the diff -u command in step 2):

-    "lastTouchedAt": "2026-01-31T15:36:29.310Z"
+    "lastTouchedAt": "2026-01-31T15:38:07.076Z"

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingstaleMarked as stale due to inactivity

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions