Updating OpenClaw Safely: Global Install and Source

Learn how to update OpenClaw using the recommended command, switch channels, and roll back safely. Essential for all OpenClaw users managing installations.

Read this when

  • Updating OpenClaw
  • Something breaks after an update

Keep OpenClaw current.

For image swaps involving Docker, Podman, or Kubernetes, refer to Upgrading container images. Before readiness, the gateway performs upgrade work that is safe at startup, and it halts if mounted state requires manual intervention.

It detects your install type (npm, pnpm, Bun, or git), pulls the newest version, executes openclaw doctor, and relaunches the gateway.

openclaw update

Switch channels or lock onto a particular version:

openclaw update --channel beta
openclaw update --channel extended-stable
openclaw update --channel dev
openclaw update --dry-run   # preview without applying

openclaw update lacks the --verbose flag (the installer has it). For diagnostics, use --dry-run to see what would happen, --json for structured output, or openclaw update status --json to check channel and availability state.

--channel beta favors the beta npm dist-tag, but reverts to stable/latest when the beta tag is absent or its version trails the newest stable release. For a one-off package update tied directly to the raw npm beta dist-tag, use --tag beta instead.

--channel extended-stable handles only packages, and installation stays foreground-only. OpenClaw reads the public npm extended-stable selector, confirms the exact package chosen, and installs precisely that version. Missing or inconsistent registry data fails closed; it never falls back to latest. If the chosen version is older than what is installed, the standard downgrade confirmation still applies. After a successful core update, the CLI persists the channel; a direct npm install -g openclaw@extended-stable --allow-scripts=openclaw does not modify update.channel, but a final extended-stable package version still checks only the verified extended-stable selector for update availability. That direct command works with npm 12 or npm 11.16+. On npm 11.15 and earlier, leave out --allow-scripts=openclaw. Following the core swap, eligible official npm plugins with bare/default or latest intent converge to that exact core version. Exact pins and explicit non-latest tags, third-party plugins, and non-npm sources stay untouched. Catalog installs from current OpenClaw versions keep that default intent. Older records holding only an exact version remain pinned because OpenClaw cannot reliably tell an old automatic pin from a user pin; run openclaw plugins update @openclaw/name once on the extended-stable channel to bring that plugin back into exact-core tracking.

--channel dev provides a persistent moving GitHub main checkout. Package installs reject the --tag main shorthand because the workspace checkout is not a self-contained package artifact. Use openclaw update --channel dev to move to the supported checkout and build flow. Other explicit package specs retain their package-manager behavior.

For managed plugins, a missing beta release counts as a warning, not an error: the core update can still proceed while a plugin falls back to its recorded default/latest release.

See Release channels for channel semantics.

Switch between npm and git installs

Installer-driven switches verify the replacement before the working owner is retired. Source wrappers publish atomically; same-path npm shim transitions use an identity-checked backup that restores on failure, so a failed candidate leaves the previous command runnable. The openclaw update command prints its final success result only after post-core convergence and requested restart health checks succeed.

Use channels to change the install type. The updater keeps your state, config, credentials, and workspace in ~/.openclaw; it only alters which OpenClaw code install the CLI and gateway use.

# npm package install -> editable git checkout
openclaw update --channel dev

# git checkout -> npm package install
openclaw update --channel stable

Preview the install-mode switch first:

openclaw update --channel dev --dry-run
openclaw update --channel stable --dry-run

dev ensures a git checkout, builds it, and installs the global CLI from that checkout. The stable, extended-stable, and beta channels use package installs. Extended-stable is rejected on a git checkout without mutating or converting it. If the gateway is already installed, openclaw update refreshes the service metadata and restarts it unless you pass --no-restart.

For package installs with a managed Gateway service, openclaw update targets the package root used by that service. If the shell openclaw command comes from a different install, the updater prints both roots and the managed service's Node path, and checks that Node version against the target release's engines.node requirement before replacing the package.

Source-checkout servers (reference script)

Teams running a gateway directly from a git checkout on a server can update it with scripts/update-gateway.sh from inside that checkout. It is the reference for an efficient source-server update: it restores tracked build outputs that pnpm build rewrites, fails closed on any other local changes, fast-forwards main (or rebases a local server branch onto origin/main), installs dependencies, builds clean, and restarts the gateway.

Generated output roots such as dist, dist-runtime, and package-local dist directories must be real directories. Builds refuse symbolic-link roots before reading or mutating their contents so cleanup cannot affect the link target. Replace an output-root symlink with a real directory before updating or building a source checkout.

ssh you@server 'cd /path/to/openclaw && scripts/update-gateway.sh'

Override the restart for custom service units, or skip it entirely:

OPENCLAW_UPDATE_RESTART_CMD='systemctl --user restart openclaw-gateway.service' scripts/update-gateway.sh
OPENCLAW_UPDATE_RESTART_CMD='' scripts/update-gateway.sh

For a plain single-user source install, prefer openclaw update --channel dev instead: it manages the checkout, build, and gateway restart for you.

Alternative: re-run the installer

curl -fsSL https://openclaw.ai/install.sh | bash

Add --no-onboard to skip onboarding. To force a specific install type, pass --install-method git --no-onboard or --install-method npm --no-onboard.

If openclaw update fails after the npm package install phase, re-run the installer instead. It does not call the updater; it runs the global package install directly and can recover a partially updated npm install.

curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method npm

Pin the recovery to a specific version or dist-tag with --version:

curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method npm --version <version-or-dist-tag>

Alternative: manual npm, pnpm, or bun

This npm command targets npm 12 or npm 11.16+. If you are on npm 11.15 or earlier, drop --allow-scripts=openclaw.

npm i -g openclaw@latest --allow-scripts=openclaw

For supervised installs, openclaw update is the recommended approach: it can synchronize the package swap with the active Gateway service. When updating manually on a supervised install, halt the managed Gateway first. Because package managers overwrite files in place, a live Gateway could attempt to load core or plugin files while the swap is happening. Once the package manager finishes, restart the Gateway so it loads the fresh installation.

On a root-owned Linux system-global install, if openclaw update errors with EACCES, fall back to system npm for recovery while the Gateway remains stopped during the manual replacement. Apply the same profile flags and environment you typically use for that Gateway. Swap /usr/bin/npm for the system npm that holds the root-owned global prefix on your machine:

The npm command below adheres to the same version contract: include the flag on npm 12 or npm 11.16+, and exclude it on npm 11.15 and earlier.

openclaw gateway stop
sudo /usr/bin/npm i -g openclaw@latest --allow-scripts=openclaw
openclaw gateway install --force
openclaw gateway restart

Then confirm:

openclaw --version
curl -fsS http://127.0.0.1:18789/readyz
openclaw plugins list --json
openclaw gateway status --deep --json
openclaw doctor --lint --json

When openclaw update handles a global npm install, it first places the target in a temporary npm prefix. During preinstall, the candidate package validates the host Node version; only after that does OpenClaw check the packaged dist inventory and move the clean package tree into the real global prefix. A packed completion guard is left out of the expected inventory and gets removed only once preinstall completes, so skipped lifecycle scripts also cause failure before the swap. The updater probes the owning npm prior to any mutation. On npm 11.15 and earlier it skips the unsupported lifecycle-policy flag. On npm 12 and npm 11.16+, it authorizes only the candidate OpenClaw lifecycle; transitive dependency scripts stay unauthorized. This prevents npm from layering a new package over stale files from the prior one. Should the install command fail, OpenClaw makes one retry with --omit=optional, which assists hosts where native optional dependencies cannot build.

OpenClaw-managed npm update and plugin-update commands also purge npm's min-release-age supply-chain quarantine (or the older before config key) for the child npm process. That policy exists for general safety, but an explicit OpenClaw update means "install the chosen release immediately."

pnpm add -g --allow-build=openclaw openclaw@latest

If pnpm 11 installed OpenClaw 2026.7.1, execute that manual command once. That version predates pnpm 11's isolated global-package layout, so its updater can confuse another npm installation with the running CLI. Later releases keep pnpm ownership and track the replacement package root during updates. They also rely on the owning manager's reported global bin directory and halt before mutation when the available pnpm command points to a different global root or major, or when the invoking package is orphaned or not the sole active OpenClaw install there.

When OpenClaw shares a pnpm 11 global install group with another package, the automatic updater stops before altering the group. Update the original comma-separated group by hand so its sibling packages and build policy remain untouched.

bun add -g --trust openclaw@latest

--trust permits OpenClaw's lifecycle scripts. The canonical openclaw update path applies the same OpenClaw-only Bun trust when it owns the install.

Advanced npm install topics

Read-only package tree

OpenClaw considers packaged global installs read-only at runtime, even if the current user can write to the global package directory. Plugin package installs reside in OpenClaw-owned npm/git roots under the user config directory, and Gateway startup does not modify the OpenClaw package tree.

Certain Linux npm setups place global packages under root-owned directories such as /usr/lib/node_modules/openclaw. OpenClaw accommodates that layout because plugin install/update commands write outside that global package directory.

Hardened systemd units

Grant OpenClaw write access to its config/state roots so explicit plugin installs, plugin updates, and doctor cleanup can persist their changes:

ReadWritePaths=/var/lib/openclaw /home/openclaw/.openclaw /tmp

Disk-space preflight

Before package updates and explicit plugin installs, OpenClaw performs a best-effort disk-space check on the target volume. Low space triggers a warning with the checked path, but does not block the update because filesystem quotas, snapshots, and network volumes can shift after the check. The actual package-manager install and post-install verification remain the final authority.

Auto-updater

Disabled by default. Turn it on in ~/.openclaw/openclaw.json:

{
  update: {
    channel: "stable",
    auto: {
      enabled: true,
    },
  },
}

The update channel and automatic updates can also be configured from Settings → Updates (/settings/updates) in the Control UI. Failures logged on that page include typed Check status and Retry update actions when the connected Gateway supports them. For reason codes, guided recovery, CLI fallbacks, and diagnostics to gather, see Update troubleshooting. For a dev git install, opening this page refreshes the tracked upstream and indicates whether the checkout is current, ahead, diverged, unavailable, or a certain number of commits behind. It also shows exact and relative build, verified install, and last-commit times. Existing checkouts display an unknown install time until their next verified successful update.

ChannelBehavior
stableAfter a built-in delay with deterministic jitter for a spread rollout, announces an update campaign.
extended-stableChecks for a read-only update hint on startup and every 24 hours when checkOnStart is enabled. Never applies automatically.
betaChecks on a built-in interval and announces an update campaign as soon as a newer release is available.
devWith auto.enabled, git installs check hourly. When upstream commits are available, the Gateway announces an update campaign pinned to the exact announced commit.

Update campaigns

When an automatic update is due, the campaign waits for active work to finish, then starts a one-minute countdown. Once that countdown begins, new work does not reset it or send the campaign back to waiting. A 15-minute hard deadline starts the update even if work remains, using the normal restart drain and session-recovery path. Open terminal sessions do not defer the countdown or apply. The Gateway restart ends these process-local PTYs, and terminal sessions are not recovered afterward.

An admin can use Hold 1 h once to postpone the campaign and shift its hard deadline, or pick Update now from the sidebar update card or Settings → Updates. For a dev git install, the campaign installs the exact commit it announced. The displayed list previews up to five commits from that fixed target and does not move if upstream main advances during the countdown.

Every failed apply ends the campaign so the UI does not stay on Updating…. Failures after a managed-service handoff starts are also recorded in the restart sentinel and surface after the Gateway returns; direct unsupervised failures remain in the running Gateway's logs.

OPENCLAW_NO_AUTO_UPDATE=1 and external-supervisor mode disable automatic applies entirely. Startup update hints can still run unless update.checkOnStart is also disabled.

The gateway also logs an update hint on startup (disable with update.checkOnStart: false). Stored extended-stable selections use this read-only hint path and the existing 24-hour hint interval, but never invoke automatic installation, handoff, restart, stable delay/jitter, or beta polling.

Package-manager updates requested through the live Gateway control-plane (update.run) do not replace the package tree inside the running Gateway process. On managed service installs, the Gateway starts a detached handoff, exits, and lets the normal openclaw update --yes --json CLI path stop the service, replace the package, refresh service metadata, restart, verify the Gateway version and reachability, and recover an installed-but-unloaded macOS LaunchAgent when possible. If the Gateway cannot make that handoff safely, update.run reports a safe shell command instead of running the package manager in-process.

The Control UI sidebar update card shows Update Gateway when it will start this update.run flow directly. This covers browser-hosted Control UI, remote Gateways, and manually managed local Gateways.

Manual updates launched from the Control UI always request confirmation first. Clicking the update card in the sidebar or Settings → Updates → Update now initially shows a dialog that names the target, lists the installed and available versions when those are known, and states the restart impact; nothing is transmitted until you confirm with Update and restart. Closing the dialog via Cancel, Escape, or dismissing it leaves the Gateway untouched. Automatic campaigns, the CLI, and update.run API clients remain unaffected.

For the signed macOS app, when the Gateway is locally owned by the app, that card changes to Update Mac app + Gateway. Sparkle handles the app update first; after relaunch, the app executes openclaw update --tag <app-version> --json, restarts its Gateway, and checks health in a setup-style progress window. That window only shows up when the managed Gateway requires an update, repair, or installation; app-only updates relaunch straight into the app. Failure details remain visible along with Retry, Update guide, and Discord actions. This coordinated path is never used for a remote or externally managed Gateway, a newer Gateway is never downgraded, and an extended-stable channel pin is never overridden.

After a successful update, the app queues a one-time welcome event for the most recent top-level direct session that had a real user/channel interaction. Cron runs, heartbeats, and background-only session updates don't affect that selection. In remote mode, the app updates only its local Mac node runtime and sends the event only when the connected remote Gateway is at least as new as the app.

After updating

Run doctor

openclaw doctor

Config migration, DM policy auditing, and gateway health verification are handled. More details: Doctor

Restart the gateway

openclaw gateway restart

Verify

openclaw health

Rollback

Rollback operates on two levels:

  1. Reinstall older OpenClaw code while preserving the current state.
  2. Restore pre-update state only when the older code cannot handle a migrated config or database.

Begin with a code-only rollback. Restoring state discards any changes made after the backup.

Before updating: create a verified backup

openclaw update keeps an automatic pre-update config copy, but it doesn't create a full state recovery point. Before a significant update, make one explicitly:

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. Since the archive may contain credentials, auth profiles, and channel state, store it with owner-only permissions and the same protection as the live state directory. See Backup for files that are included and those intentionally omitted.

For a byte-for-byte recovery point that includes volatile artifacts not in the portable archive, stop the Gateway and use a filesystem, volume, or VM snapshot from your platform.

Roll back a package install

List published versions, then preview and install the known-good version:

npm view openclaw versions --json
openclaw update --tag <known-good-version> --dry-run
openclaw update --tag <known-good-version>

openclaw update --tag is preferred over a direct package-manager install. It detects the downgrade, asks for confirmation, runs managed plugin convergence and compatibility checks against the installed target, refreshes service metadata, restarts the Gateway, and verifies the running version. If the stored channel is extended-stable, use --channel stable --tag <known-good-version> because exact one-off tags cannot be combined with the extended-stable selector.

Package updates stage and verify the candidate before activation. If the filesystem swap or command-shim replacement fails, OpenClaw restores the old package automatically. After a successful swap, a later Gateway health failure reports the previous version and manual rollback instructions instead of automatically replacing the package again.

If the CLI update path is unavailable, use the same package manager and install scope that own the current Gateway:

The npm command below is for npm 12 or npm 11.16+. On npm 11.15 and earlier, omit --allow-scripts=openclaw.

openclaw gateway stop
npm i -g openclaw@<known-good-version> --allow-scripts=openclaw
openclaw gateway install --force
openclaw gateway restart

For a pnpm-owned install, use pnpm add -g --allow-build=openclaw openclaw@<known-good-version> instead. For a Bun-owned install, use bun add -g --trust openclaw@<known-good-version>; --trust allows OpenClaw's lifecycle scripts. During incident recovery, prevent an enabled auto-updater from immediately applying a newer release by setting OPENCLAW_NO_AUTO_UPDATE=1 in the Gateway environment.

Roll back a source checkout

Use a clean checkout and select a known-good tag or commit:

git fetch --all --tags
git checkout --detach <known-good-tag-or-commit>
pnpm install && pnpm build
openclaw gateway restart

To return to latest: git checkout main && git pull.

The updater automatically returns a git checkout to its previous branch and SHA when dependency installation, build, UI build, or doctor fails after a git update starts. Manual checkout is still required when you intentionally choose an older commit.

Downgrading across the session SQLite migration

Before starting an older file-backed OpenClaw release, use the current CLI to restore archived legacy transcript artifacts:

openclaw gateway stop
openclaw doctor --session-sqlite restore --session-sqlite-all-agents

This does not delete SQLite data. Sessions created after the SQLite migration exist only in SQLite and will not appear to the older runtime. See Downgrading after session SQLite migration.

Restore state only when necessary

If the older code cannot read a newer config or database schema, stop the Gateway and restore the verified pre-update filesystem, volume, or VM snapshot. Preserve the current state separately before restoring because this removes changes made after the snapshot.

Restore a broad archive to a fresh staging directory with the current CLI:

openclaw backup restore <archive.tar.gz> --target <fresh-directory>

The command verifies the archive and its SQLite databases before extraction. Activation remains an explicit offline step: stop the Gateway, move the restored asset tree into place or point OPENCLAW_STATE_DIR at the restored state asset, run openclaw doctor, then restart.

Treat a state restore as time travel. Ratcheting channel credentials, especially WhatsApp, can desynchronize and require relinking. Approvals and delivery/dedupe state roll back too, and plugin node_modules trees are not archived. See Restore a full archive for the complete activation and recovery sequence. openclaw backup sqlite restore likewise writes a verified database to a fresh target; activating that target remains an explicit offline operator step.

Verify the rollback

openclaw --version
openclaw health
openclaw plugins list --json
openclaw gateway status --deep --json
openclaw doctor --lint --json

If you are stuck

  • Run openclaw doctor again and read the output carefully.
  • 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
  • Ask in Discord: https://discord.gg/clawd
3,415 words · updated Aug 25, 2026