# Rollback and recovery

> Downgrading, automatic schema-neutral rollback, verified pre-update backups, and triage when an update leaves you stuck

- 网址：https://funcoding.ai/agents/openclaw/install/updating/rollback-and-recovery/
- 来源：OpenClaw 官方文档原文（英文），MIT 许可，同步于 2026-10-11
- 官方原文：https://docs.openclaw.ai/zh-CN/install/updating/rollback-and-recovery

---
Downgrades, automatic rollback, verified pre-update backups, and triage when an update leaves you stuck. Part of the [Updating](https://funcoding.ai/agents/openclaw/install/updating/) guide.

## Before you upgrade

- Create a [verified backup](#before-updating-create-a-verified-backup) and keep the same service account, profile, and state/configuration paths.
- Compare `openclaw --version` with `openclaw status` and `openclaw gateway status --deep`. The first reports the CLI version; status reports a Gateway service targeting a different installation. In `openclaw status --json`, compare `update.root` with `gatewayService.layout.packageRootReal`; `gatewayService.layout.entrypointReal` identifies the service binary, and `gatewayService.installationDrift` explains a mismatch.
- Check the actual Node executable and version with `node -p "process.execPath + ' ' + process.version"`. Compare them with the updater's detected runtime and required range, since the service can select a different Node than your shell. See [supported Node versions](https://funcoding.ai/agents/openclaw/install/node/).
- Run `openclaw update --dry-run` and inspect any named preflight check. Restore service-manager access as the owning account when requested. An unavailable manager produces a warning and skips automatic service restart; an ownership refusal requires resolving the reported mismatch before retrying.
- If installation paths differ, align entry points before considering a reinstall. On Windows, use `Get-Command openclaw -All` and `Get-Command node -All`; on macOS/Linux, use `type -a openclaw node`. Retry through the intended installation's absolute launcher and follow the updater's recovery command. Changing the shell's Node alone does not update the service definition.

Preflight diagnostics identify the update installation and binary, the detected
runtime, and the service installation when inspected. An unresolved service path
means it could not be verified, not that no Gateway is running. Older installed
updaters keep their original messages for the first upgrade hop.

## Downgrade

Verify the upgrade and your session history before retiring recovery originals
with `openclaw update cleanup`. Downgrading the package does not reverse config
or database migrations. Once state has migrated beyond the older release's
supported format, the supported recovery is to restore a verified pre-update
backup with its matching OpenClaw release.

<div class="callout callout-warning">

Fresh shared-state databases created after tenant-container management was retired
omit `fleet_cells`. Older revisions that require this table can reject them even
when the numeric schema version matches. Existing databases retain the old table
and rows, but that alone does not establish downgrade compatibility. Do not
reconstruct the retired table or alter schema markers to bypass validation.
Continue with the current release, or restore a complete verified backup with its
matching older release using the recovery procedure below.

</div>

Prefer `openclaw update` for upgrades and recovery. It validates the target,
runs required Doctor migrations, and verifies the activated Gateway. A raw
`npm i -g` replacement does not retain the previous package or run this recovery
workflow; use `openclaw update` or [create a backup first](#before-updating-create-a-verified-backup).

The updater retains the previous package during activation and keeps it when
failed recovery cannot prove a working installation. Migration recovery originals
and original-state update captures remain until explicit
[update cleanup](https://funcoding.ai/agents/openclaw/cli/update/#update-cleanup). These are
separate recovery mechanisms: cleanup does not manage package or Git runtime
backups, and retained migration originals are not a full pre-update backup.
Preserve every recovery location named in the update report until you have
verified the installation.

Launcher backups compare the link type and target, plus ownership when it can
be preserved. Symlink permission bits do not block an update; macOS link modes
are copied when supported. Regular-file launchers still require matching modes
and contents. If backup verification fails, the report names the differing
fields and the retained failed copy for inspection before retrying.

Package rollback checks file hashes, inode identity, permissions, ownership, and
symlink targets. It ignores regular `node_modules/.package-lock.json` files,
which npm documents as a disposable cache, and link counts and change times
that can change without altering the retained bytes. Executable `.bin` entries
remain part of verification. During the original update process, a mismatch
records up to five differing relative paths and field names (including `sha256`
for changed contents) in the failure facts and report. Recovery after a process
restart retains the saved digest check but cannot reconstruct that entry list.

This behavior belongs to the installed updater. An older updater, including
2026.9.4, can refuse package or launcher verification before the target version runs
and cannot gain these diagnostics from the candidate.
Use the installation's [manual package-manager update procedure](https://funcoding.ai/agents/openclaw/install/updating/update-methods/#alternative-manual-npm-pnpm-or-bun)
if that first update is blocked.

For a target that can read the current state, preview and use the managed
rollback path:

```bash
openclaw update --tag <known-good-version> --dry-run
openclaw update --tag <known-good-version>
```

The updater checks compatibility and asks for downgrade confirmation. If the
saved channel is `extended-stable`, add `--channel stable` for an exact one-off
tag. Supported targets finalize the config writer stamp, restart the service,
and verify the running version. Older targets may lack that finalization or
migration-continuation contract; follow the printed recovery guidance if
activation is refused. Do not bypass a newer-schema or newer-config refusal.

When the update report identifies retained originals, use the corresponding
[Doctor recovery command](https://funcoding.ai/agents/openclaw/cli/doctor/#session-sqlite-migration) before cleanup.
Restoring legacy session artifacts does not reverse SQLite schemas or restore
sessions created only in SQLite. If the older release cannot read the current
state, restore the pre-update backup using [Restore a full archive](https://funcoding.ai/agents/openclaw/install/backups/#restore-a-full-archive).
Keep the Gateway and other writers stopped throughout activation of the restored
state, and preserve the current state separately first: restoration discards
changes made since the backup. Reinstall the matching package through the
installation's package manager; a backup archive does not contain the package.

A complete recovery point must cover these together:

- The matching OpenClaw package version or source revision and built runtime.
- `openclaw.json`, including `meta.lastTouchedVersion`.
- `state/openclaw.sqlite` and every `agents/<id>/agent/openclaw-agent.sqlite`,
  including databases at configured paths outside the default layout.
- The workspaces, credentials, and retained originals needed by that installation.

Restore that set from one backup generation. Do not combine a pre-update config
or shared database with a post-update per-agent database, or the reverse. Model
auth profiles and their state are authoritative in each
`openclaw-agent.sqlite`. Files named
`auth-profiles.json.sqlite-import.<id>.bak` or
`auth-state.json.sqlite-import.<id>.bak` are preserved migration inputs or
recovery artifacts, not the live credential store. Restoring those JSON files
without the matching per-agent database does not restore that generation's auth
state.

Use `openclaw backup create --verify` for a verified, WAL-aware archive. Never copy only the
main `.sqlite` file from a live WAL database: committed data can still be in
`-wal`. Restore the verified consolidated database offline; do not mix it with
`-wal` or `-shm` files from another database generation. See [Backup](https://funcoding.ai/agents/openclaw/cli/backup/)
for archive coverage and omissions.

Versions with the [startup preflight repair](https://github.com/openclaw/openclaw/pull/141451)
leave configuration, databases, and migration inputs unchanged when preflight
refuses startup. A successful start can migrate state forward. An older binary may then refuse
both the database schema and the config's `meta.lastTouchedVersion`; changing
either version marker does not undo the migration. Repair the installed version
with `openclaw doctor --fix --non-interactive`, or use the backup recovery above.

During recovery, prevent an enabled [auto-updater](https://funcoding.ai/agents/openclaw/install/updating/automatic-updates/#auto-updater) from immediately
reapplying the newer release by setting `OPENCLAW_NO_AUTO_UPDATE=1` in the Gateway
environment.

After recovery, verify the running installation before cleanup:

```bash
openclaw --version
openclaw health
openclaw gateway status --deep --json
openclaw doctor --lint --json
openclaw update cleanup --dry-run
```

<a id="automatic-checkpoint-recovery" />

### Full-state recovery requires a backup

Package updates keep pre-migration SQLite snapshots alongside the package
backup until verified successful activation removes them with that backup.
Rollback, failed or unverified completion, and refused restoration retain them.
If cleanup cannot finish, the update reports a maintenance warning with the
retained path. Older snapshot directories are not automatically removed: their
ownership and successful outcome cannot be proven from existing receipts.
Doctor reports older npm snapshot directories with their size and removal command.
Confirm no update is in progress and inspect the corresponding update report and
recovery state before manual cleanup.
If the Gateway was confirmed stopped during capture, a failed candidate
that was never allowed to start can restore those databases before package
rollback only when database write fingerprints remain unchanged through Doctor
and restoration. Maintenance ownership cannot identify independent SQLite writers,
so any change during Doctor, including Doctor's own writes or a newly created
database, makes these snapshots available for manual recovery only. A change between
capture and Doctor admission, during Doctor, or after Doctor finishes preserves the current
databases and reports `state-migrated-no-rollback` with the snapshot location and
Doctor recovery guidance. Without Doctor write evidence, rollback requires the
last verified database generations to remain unchanged.
Snapshot capture first settles local SQLite writers under maintenance ownership,
so later writer shutdown is not mistaken for intervening writes. The installed
updater owns this ordering; staging a newer candidate cannot change an
already-running older updater.
On Windows, an eligible capture first runs the same native SQLite exclusion check
used by rollback. This settles any retained WAL before recording write fingerprints,
so later check cleanup is not mistaken for another writer. If another connection
prevents exclusion, snapshots remain available for manual recovery.
Snapshots taken while a Gateway may still be writing are available for
manual recovery only until verified successful activation, even if it exits later.
Migrated files are kept as
`<database>.migrated-<runId>` for inspection, and the report names the snapshots
and displaced files. See [Recovery limits](https://funcoding.ai/agents/openclaw/cli/update/how-updates-run/#recovery-limits)
for disk requirements and the lifecycle checks.

Database restoration preserves current update history, including failure details
recorded after capture. The retained original snapshots remain unchanged.

This requires the repaired updater to drive the update; already-running older
drivers cannot gain database rollback from the candidate. A candidate that
may have served keeps the existing refusal to avoid discarding newer writes.
Replacing its package alone cannot reverse migration. Use a verified pre-update
backup with its matching release for an intentional downgrade. The updater
does not create or replay a full-state checkpoint.

An existing pending checkpoint-recovery record blocks further mutable updates.
The updater reports that it is unsupported and leaves its records, backups, and
state unchanged. Do not remove or alter retained artifacts to force a clean
status, and do not use `update finalize` to bypass the refusal. Preserve the
reported locations for a compatible recovery implementation or an independent
verified backup. An interrupted or refused restore is not a successful rollback.

### Automatic schema-neutral rollback

If a newly activated package fails verification, `openclaw update` compares the
shared and affected per-agent SQLite `user_version` values with their
pre-activation values and checks that the config file still matches the content
reported by the new version’s activation Doctor writer.
Databases first created during activation or verification are
schema-neutral when their version matches the new version's supported version for
that database kind. A changed schema version or missing pre-existing database,
or a new database at a foreign version, still blocks rollback. Before restoring
code, the updater also checks that the previous package supports any new database;
unknown or incompatible support refuses rollback with `rollback-state-unverified`.
When both checks pass and the retained previous package was verified before the
update, it stops the new version and restores the previous generation: package,
command shim, service definition, and exact pre-activation config bytes, including
the previous writer stamp. Config replacements use owner-only permissions (`0600`);
unchanged config needs no write. Owned, writable
service metadata is refreshed; protected service definitions are preserved.
The CLI verifies the restarted previous Gateway's service health, version/build
identity, plugins, channels, and `/readyz` again. Update verification does not use
model inference: the managed service must be running and own its port, and the
Gateway hello handshake must match the expected artifact.

The new version’s Doctor migrations in the main config file and its `$include` files do not block rollback, including on
a fresh install’s first update. The updater retains the config immediately before
Doctor and verifies that Doctor consumed those captured bytes before making changes.
It also checks each current file against the output hash reported by Doctor’s writer.
Rollback restores the original bytes only while both hashes match. Restoration
holds the normal config writer locks and rechecks the files after acquiring them. Operator edits
made after activation block restoration, including edits before Doctor reads the
config and between Doctor’s last write and the updater’s capture. Changed include paths
also block restoration. Older updater handoffs that retain only the root file still
require includes to remain unchanged. The existing intentional-recovery
allowance applies only to service commands, so the older-binary guard does not
block recovery; it is never saved in config or the service environment.

Missing or malformed includes do not prevent Doctor from running. When the updater
cannot capture the complete include graph, it warns that automatic config rollback
is unavailable and leaves any Doctor repairs in place if the update later fails.

Successful recovery leaves the previous Gateway running and finishes the run as
`rolled-back`, with `after.version` set to the previous version and downtime
measured from service stop through verified recovery. The headline is
`↩️ OpenClaw update rolled back to <previous>: <reason>`, retaining the original
verification failure. The command still exits nonzero; recovery does not turn a
rejected version into a successful update.

Recovery reports distinguish restored package files from a healthy Gateway.
A verified rollback names the version serving after recovery, including when
an additional repair was needed. If the restored service fails its health check,
the result records `recovery.service: "failed"`; the report says health failed
and includes the recorded recovery reason. Health is reported as unverified only
when verification could not run or complete, such as a readiness timeout. Both
outcomes direct you to `openclaw gateway status --deep` to check the serving version
and readiness. Rollback uses the same startup allowance as the update's activation check.
Restart notifications retain the recovery fields understood by the restored runtime.
Detailed recovery reasons remain in the update result, status diagnostics, and failure report.

Use `openclaw update status` for the recorded reason and `openclaw triage` to
diagnose a failed check. Recovery guidance reports whether the Gateway is running
or stopped from the latest service observation, even when the new version is running but did
not pass verification. A restored Gateway must pass its own verification checks
before the run can finish as `rolled-back`.

In the Control UI, open **Settings → Updates** and choose **Diagnose update** to
ask OpenClaw to investigate the recorded failure. Loading the dashboard,
reconnecting, or receiving an update failure does not start diagnosis. Each
diagnostic request requires a button press; it does not retry the update.

Automatic CLI triage never follows a verified rollback; it runs only when the update
ends failed. In an interactive terminal, you can choose **Diagnose update failure**,
**Report update failure**, or **Exit**, which is selected by default. Reporting
shows the sanitized preview and requires separate confirmation before issue
creation. Skipping or cancelling does not start diagnosis or submit a report.
JSON, `--yes`, non-interactive, and managed-service handoff invocations do not
show this menu after rollback.

If the config file changed after the activation Doctor pass or the databases
remain incompatible after eligible pre-start restoration, rollback is refused with
`state-migrated-no-rollback`. For config edits, the next action names the file
whose changes blocked restoration. The updater preserves the failed outcome and migrated state. Optional
[post-failure triage](https://funcoding.ai/agents/openclaw/install/updating/#unattended-repair-on-your-own-inference)
can run after update ownership and service compensation settle, including after
failed rollback. Use the printed diagnostics and installation-specific repair
command before considering an older version. Triage does not rewrite that
failed update as successful.

On macOS and Linux, if Doctor times out after migration, the updater stops its tracked process groups
and waits for each group to disappear before attempting recovery. Once settlement
is proven, it can start the installed candidate on the preserved migrated state
and verify Gateway health. The report retains the Doctor failure, records a
maintenance warning, and recommends `openclaw update repair`; recovery does not
claim that unfinished Doctor repairs completed. If any writer remains or cannot
be accounted for, the report names the known PIDs and keeps the Gateway stopped
because concurrent writes put data at risk. Later update attempts retain this
block even if the original updater has exited. Preserve the recovery snapshots
and follow the reported process-inspection guidance before retrying repair.
The installed updater owns this process supervision: a first update driven by
2026.9.5 remains limited by that older parent's settlement checks.

Before starting a preserved candidate, the updater checks shared and existing
agent database schemas against the candidate's contract. If migrations remain
pending after the failed Doctor has stopped, it runs the candidate Doctor again
under Doctor's maintenance and backup safeguards, then checks completion before
restarting the Gateway. A refused or incomplete repair stays in the update report
with the reason and the commands `openclaw doctor --fix` followed by
`openclaw gateway start`. Newer database schemas are never downgraded by this repair.
The original update failure remains recorded even when recovery restores service.
Its durable restart notice is delivered when the Gateway starts again.

Automatic rollback restores code and captured config, and restores pre-migration
database snapshots only when the Gateway was confirmed stopped during capture
and the candidate was never allowed to start, with matching write fingerprints
through Doctor and rollback.
The temporary snapshots used to check migrations are removed after
validation and do not replace your backup.
If the schema comparison cannot be completed, automatic rollback is refused
(`rollback-state-unverified`). The newly installed version owns final
verification and reporting after migration,
preserving the same run ID and recorded activation steps.

For pnpm and Bun, changes to sibling global packages after staging refuse automatic rollback (`rollback-project-changed`) without restoring the shared project; keep a reachable version installed, otherwise keep the Gateway stopped and follow the report’s repair command.
A refusal before the live swap restarts the unchanged Gateway and preserves the sibling changes.

### Before updating: create a verified backup

`openclaw update` preserves an automatic pre-update config copy, not a full-state
recovery point. Before a significant update, create an independent verified backup
explicitly:

```bash
mkdir -p ~/Backups/openclaw
openclaw backup create --output ~/Backups/openclaw --verify
```

The archive manifest records the OpenClaw version and the source paths included
in the backup. The archive can contain credentials, auth profiles, and channel
state, so store it with owner-only permissions and the same protection as the
live state directory. See [Backup](https://funcoding.ai/agents/openclaw/cli/backup/) for included and intentionally
omitted files.

For a byte-for-byte recovery point that includes volatile artifacts omitted by
the portable archive, stop the Gateway and use a filesystem, volume, or VM
snapshot provided by your platform. This matters for older file-backed installs:
the portable archive omits matching JSONL transcripts and logs even when they
are no longer being written.

When migrating large legacy histories, leave room for the original files, a
temporary SQLite spool, and the destination database/WAL simultaneously. SQLite
can be larger than the original JSONL; streaming import does not imply a fixed
RAM requirement or migration time. Check free space on both the system temporary
volume and the state volume. See [Session SQLite migration](https://funcoding.ai/agents/openclaw/cli/doctor/#session-sqlite-migration)
for staging and memory details.

## If you are stuck

Run `openclaw triage` in a terminal on the Gateway host, using the printed
installation-specific command or keeping the same profile and state/config
overrides. It opens the first directly launchable coding agent in this order:
Claude Code, Codex, OpenCode, then Pi. The agent receives local diagnostics and
any recorded failed-update outcome so it can repair the installation and verify
Gateway health, using its normal authentication, sandbox, and approval settings.
Use `openclaw triage --agent codex` to select a particular agent.

Failed interactive updates offer triage after updater cleanup and
pass the captured failure to the agent before fresh diagnostics can delay the
handoff. Before launch, OpenClaw shows the agent, saved prompt path when available,
and use of your own account/tokens. Only an affirmative Yes proceeds. Enter, `n`,
cancellation, or 30 seconds without an answer skips the launch, prints a manual
recovery command, and preserves diagnostics and the failed update's exit status.
Explicit `openclaw triage` does not ask for this confirmation.
JSON, `--yes`, and non-interactive update invocations can start one owned automatic
repair after an eligible failure; other failures retain diagnostics and handoff
commands. For diagnostic collection
alone, use `openclaw triage --non-interactive`; add `--update-result <path>` to
include a saved update-failure artifact. See [Triage](https://funcoding.ai/agents/openclaw/cli/triage/) for command
formatting and installation targeting.

Triage keeps the failed update's report intact. An update started during repair
creates its own history entry. After package replacement, restart commands run
from the updated installation. A restart accepted by the service owner can still
fail readiness checks; inspect `openclaw gateway status --deep` before retrying.

Keep a stopped, unverified Gateway stopped and preserve migrated state during
repair. A reachable version retained after a schema migration can continue
serving while you diagnose it.
The failed update retains its nonzero exit code even if the agent repairs it.

- For `openclaw update --channel dev` on source checkouts, the updater auto-bootstraps `pnpm` when needed. If you see a pnpm/corepack bootstrap error, install `pnpm` manually (or re-enable `corepack`) and rerun the update.
- Check: [Troubleshooting](https://funcoding.ai/agents/openclaw/gateway/troubleshooting/)
- Ask in Discord: [https://discord.gg/clawd](https://discord.gg/clawd)

### Unattended repair on your own inference

Updates, validation, verification, and rollback do not require inference or model
authentication. An unavailable model route cannot block those operations.
Validation failures discard the staged candidate while the old Gateway keeps
serving. After activation, the updater first completes its existing
compatibility-checked rollback and service-compensation flow.

Eligible failed updates can then start one owned triage repair after their update
ownership has been released. Triage targets the installation that remains,
preserves migrated state, and keeps the original failed update's outcome and
nonzero exit code. Successful repair does not retrospectively publish a successful
update or verified rollback. Reports from older updaters can still contain a
`repairing` phase and its attempt summaries.

Published 2026.9.4 updaters may invoke the candidate's repair-worker entry before
the update settles. New candidates retain its response protocol but report
inference repair unavailable without loading a model or changing operator state.
The published driver still owns that first update's control flow and budgets.

For an explicit repair using configured inference, run `openclaw triage --run`
in a terminal on the Gateway host. Triage runs Doctor health checks, attempts
up to one embedded repair turn with time and tool-call limits, and runs Doctor
again. It uses the normal runtime credential resolver, including inherited
profiles and OAuth refresh; unavailable inference produces an external handoff
rather than a login prompt. The repair keeps the existing installation scope and
tool-policy restrictions.

A saved activation or recovery failure additionally requires recorded updater
completion and current installation and Gateway verification. An attributed
Doctor/config blocker can be resolved by fresh Doctor checks and the recorded
installed identity, while its historical failed run remains unchanged. Native
service activation and recovery retain their existing authority checks. See
[Triage](https://funcoding.ai/agents/openclaw/cli/triage/#installation-target-and-embedded-handoff) for installation
targeting, repair limits, and validation results.
