A battle-tested upgrade procedure for OpenClaw, born from a real production failure where a Dashboard upgrade silently broke Gateway communication (Telegram, WebChat) with no clear error message.
Use this skill when: upgrading OpenClaw to a new version, planning a safe upgrade path, or recovering from a failed upgrade.
In March 2026, a Dashboard-triggered upgrade from 2026.3.13 to 2026.3.22 caused:
pnpm which wasn't installedentry.js → index.js) without service file migrationopenclaw doctor --fix fixed config but NOT the systemd service fileThis procedure prevents all of these issues.
NEVER upgrade via the Dashboard. Always use CLI.
bash
BACKUP_DIR="$HOME/.openclaw/workspace/backups/openclaw-upgrade-$(date -u +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"
# Config + credentials + agents
cp ~/.openclaw/openclaw.json "$BACKUP_DIR/"
cp -r ~/.openclaw/credentials "$BACKUP_DIR/" 2>/dev/null
cp -r ~/.openclaw/agents "$BACKUP_DIR/agents" 2>/dev/null
# Service file
cp ~/.config/systemd/user/openclaw-gateway.service "$BACKUP_DIR/" 2>/dev/null
# Version info
openclaw --version > "$BACKUP_DIR/state-info.txt"
npm list -g openclaw >> "$BACKUP_DIR/state-info.txt" 2>&1
echo "Backup saved to: $BACKUP_DIR"
Check https://github.com/openclaw/openclaw/releases
Red flags to watch for:
bash
openclaw doctor 2>&1 | tee "$BACKUP_DIR/doctor-before.txt"
bash
# ALWAYS use npm, never pnpm or Dashboard
npm update -g openclaw
# Verify
openclaw --version
bash
# Check what needs migration
openclaw doctor
# Apply fixes (config schema changes, deprecations)
openclaw doctor --fix
bash
# Check if entrypoint still matches
CURRENT_ENTRY=$(grep ExecStart ~/.config/systemd/user/openclaw-gateway.service | grep -oP 'dist/\K[^\ ]+')
ACTUAL_ENTRY=$(ls ~/.npm-global/lib/node_modules/openclaw/dist/index.js 2>/dev/null && echo "index.js" || echo "entry.js")
if [ "$CURRENT_ENTRY" != "$ACTUAL_ENTRY" ]; then
echo "⚠️ Entrypoint mismatch: service=$CURRENT_ENTRY actual=$ACTUAL_ENTRY — fixing..."
sed -i "s|dist/$CURRENT_ENTRY|dist/$ACTUAL_ENTRY|g" ~/.config/systemd/user/openclaw-gateway.service
echo "✅ Fixed"
else
echo "✅ Entrypoint OK"
fi
bash
systemctl --user daemon-reload
systemctl --user restart openclaw-gateway.service
sleep 5
systemctl --user status openclaw-gateway.service
TestCommand / ActionExpectedGateway runningsystemctl --user status openclaw-gatewayactive (running)Version correctopenclaw --versionNew version numberDoctor cleanopenclaw doctorNo "invalid config" errorsWebChatSend message in DashboardResponse within 30sTelegramSend message to botResponse within 30sAgents listedopenclaw statusAll agents shownCron jobsCheck cron listJobs intact
Success: Note version change + any fixes applied in your daily log.
Failure: Save all evidence, then rollback:
bash
# Capture evidence BEFORE rollback
openclaw doctor 2>&1 > "$BACKUP_DIR/doctor-failed.txt"
journalctl --user -u openclaw-gateway -n 200 > "$BACKUP_DIR/gateway-logs-failed.txt" 2>&1
openclaw --version >> "$BACKUP_DIR/failure-info.txt"
bash
# 1. Install previous version
npm install -g openclaw@<OLD_VERSION>
# 2. Restore config
cp "$BACKUP_DIR/openclaw.json" ~/.openclaw/openclaw.json
cp "$BACKUP_DIR/openclaw-gateway.service" ~/.config/systemd/user/
# 3. Restart
systemctl --user daemon-reload
systemctl --user restart openclaw-gateway.service
# 4. Verify
openclaw --version
openclaw status
ProblemCauseFixDashboard upgrade failsUses pnpm (not installed)Always use npm update -g openclawGateway won't startEntrypoint renamedFix service file (Step 6)Config invalidSchema breaking changesopenclaw doctor --fixTelegram silentGateway crashed or misconfiguredCheck service status + logs"first-time setup mode"Pairing state resetRe-pair or check configSkills path errorsSkill paths changedRe-check skill directories
If the upgrade fails and rollback is needed, file a bug at github.com/openclaw/openclaw/issues with:
openclaw doctor output (before and after)journalctl --user -u openclaw-gateway -n 200)