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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions