I run OpenClaw as a systemd user service inside WSL, mostly as a local playground for agent setups. It had been sitting on 2026.4.1 for a while, and I upgraded it to 2026.8.1 in one jump. That is four months and four major versions.
The install finished. The gateway did not start. It exited with code 78 (EX_CONFIG), and the log told me to run openclaw doctor --fix.
I ran it. It printed a list of problems. I started the gateway again. Exit 78.
This post is the order of steps that actually got it booting, and the one habit I would take into any upgrade like this: treat "run doctor --fix" as a suggestion, not a fix.
What doctor did and did not do
doctor was useful for finding things. But on this jump the problems it reported were still there after --fix, and two of its messages were actively misleading:
- It warned that
agents.listhad to becomeagents.entries. It did not rewrite it. The new shape is an object keyed by agent id instead of an array of objects with anidfield, so this is a two-minute edit, but you have to do it yourself. - It got stuck in a loop on a legacy session store:
deferred legacy-main session migration; run openclaw doctor --fix
Running doctor --fix again produced the same line. And again. The message points at the command you just ran.
The real blocker was in journalctl
The gateway's own output only gave me the exit code and the doctor hint. The service log had the actual reasons:
journalctl --user -u openclaw-gateway
That is where the actual blockers showed up. Once I stopped re-running the hint and started reading the journal, the rest was mechanical.
The order that worked
-
Node first. 2026.8.1 requires Node
>=22.22.3. The box had 22.22.1, two patch versions short, and npm refused at preinstall. I installed Node 24 with nvm and made it the default. -
Let the install scripts run. npm skipped the package's
postinstallby default, so the bundled plugins never landed. Reinstalling with--allow-scriptsforopenclawand its native dependencies fixed that. -
openclaw gateway installagain. The systemd unit still pointed at the old Node binary path, so the service was launching the new code with the old runtime. -
Delete the config keys the new schema rejects, one boot at a time. This was the slow part. Each failed boot named some of the rejected keys, not all of them. For me the full set was
meta.lastTouchedAt,commands.ownerDisplay,gateway.tailscale.resetOnExit,gateway.nodes.denyCommandsandplugins.installs. I found them over several boots. -
agents.list→agents.entries, by hand, as above. -
Add
agents.ownership: "explicit". It is now required when more than one agent is defined. -
Move the legacy stores aside.
agents/*/sessions/sessions.jsonandexec-approvals.jsonwere what kept the migration loop alive. Renaming them let the new SQLite stores be created. The cost: old chat history is gone, which is why I tarred the whole~/.openclawdirectory before touching anything. - Disable third-party plugins written against the old SDK. One chat-integration plugin could no longer be loaded from its TypeScript source and blocked boot on its own.
After step 8 it came up. The new UI is a full redesign, with sessions as a first-class pane, which was the thing I wanted from the upgrade in the first place. But nothing about getting there was automatic.
One more trap while iterating
Steps 4 to 8 mean restarting the service a lot. OpenClaw has a crash-loop breaker: three unclean boots within five minutes, and it suppresses provider auto-start on the next boot. At that point the gateway is up, but agent turns fail for a reason that has nothing to do with whatever you just fixed. It looks like your fix broke something else.
What worked: stop the service, wait about 45 seconds, start it once, and leave it alone while you read the journal.
What I would do next time
- Back up the whole config directory before upgrading, not just the config file. Some of the fixes are "rename this store aside", and that is only safe with a copy.
- Expect schema rejections to arrive in batches. Plan for several boots, not one.
- When an error message tells you to run a repair command, run it once. If the message comes back unchanged, the repair command is not going to help, and the answer is in the service log.
If you have upgraded a self-hosted agent stack across several majors at once: did its migration tool do the work, or did you end up editing config by hand too?
Top comments (0)