Guide

Update Hermes Agent and Hermes WebUI Without Breaking Sessions

Update a self-hosted Hermes Agent and its Web UI in the right order: check upstream, confirm the clone, sync dependencies, restart the gateway, and confirm the session survived.

An update should cost you a minute of uptime, not a lost conversation. The trap is that a self-hosted Hermes setup is more than one checkout. The agent and the separate community WebUI can each be sitting on different code, and restarting them in the wrong order leaves one of them running something stale.

This guide covers a source install of Hermes Agent and the independent Hermes WebUI. The behaviour below comes from the updating docs and the two repositories, checked in October 2026. It is a documented workflow, not a record of one particular machine.

What you need

1. Check what upstream has before you pull

Do not pull blind. The updater can tell you what is waiting without changing a file.

hermes update --check

On a source install this fetches the tracked branch and prints either Already up to date or Update available: N commits behind main. For a fuller picture before you commit, hermes update --plan is read-only. It prints the install kind, every Hermes service running from that install across your profiles, its supervisor, the code version it is running, and how the update will restart each one.

For the human-readable version of what changed, read the releases page. A release that renames a config key or changes a stored format is the one to schedule time for.

2. Confirm your clone is complete enough

The installer does not hand you a full clone. On Linux and macOS it clones with a blob filter, so you get every commit, tree and release tag, and file contents are fetched from the remote on demand. That is fine for hermes update, but it changes what your own git commands do. Know which kind of checkout you have.

Run these inside the agent checkout:

git rev-parse --is-shallow-repository
git config --get remote.origin.partialclonefilter

The first prints true only for a depth-limited clone, and the second prints the filter for a partial clone. Why it matters:

3. Let the updater install dependencies

Do not hand-run pip or npm. hermes update delegates dependency preparation to PM, the provisioning layer, which pins Python, Node.js, npm, ripgrep and FFmpeg, then builds a complete Python environment from the new lock and the extras you already have enabled. A plugin that no longer fits the new core is disabled with a printed warning instead of failing the whole update.

hermes update

The command prints each phase as it runs: the pre-update state snapshot, the code update, a post-pull syntax check that rolls the checkout back to its previous commit if a critical file fails to parse, dependency preparation, config migration, a desktop rebuild if you built the app from source, and the gateway restart.

If the update added configuration options, it prompts you to set them. If you skipped that prompt, catch up later:

hermes config check
hermes config migrate

4. Restart the gateway in the right order

Order is the whole point. On Linux and macOS, hermes update already does the correct thing for you. It pauses every gateway running from that install right before it first changes the checkout, then starts exactly that set again on the new code once dependencies are prepared. It prints one line naming what it paused (Paused for the update) and one when the service is back (Restarted paused gateway(s)).

That restart is drain-first. The gateway refuses new turns, then waits for in-flight work to finish before it exits, capped by agent.restart_after_turn_timeout, which defaults to 30 minutes. A long cron job or a running turn is not cut off mid-flight. The updater prints what it is still waiting on, every 30 seconds.

Two cases where you restart something yourself:

The WebUI comes after the agent. Because the WebUI runs the agent in-process, it keeps serving the code it loaded at startup until you restart it. Its built-in updater applies the agent first and the WebUI second for exactly this reason. For which parts of the setup belong to which checkout, see Hermes Agent vs Hermes WebUI: what actually gets restarted. If you do it by hand, restart the WebUI’s server once the agent update has finished:

cd hermes-webui
git pull
./ctl.sh restart

Under a supervisor, restart the unit instead of using ctl.sh, and keep the WebUI on the agent’s Python interpreter so it can import the new agent code.

5. Verify the session survived

The update replaces the code checkout, not your session store. What you are checking is that the gateway came back on the new code and your history is still there.

hermes status
hermes gateway status --deep
hermes sessions list --limit 10

hermes status should show the gateway running. hermes sessions list shows recent sessions in your store. To reopen the last conversation, hermes --resume latest picks it up (or hermes --continue). If you started the update from a chat session with /update, that session survives the pause: the updater moves itself into its own scope first, so the conversation that asked for the update is the one that comes back.

If something looked wrong, the run left a record:

hermes logs update

The receipt names the outcome and any follow-ups. An owed step, like a build that failed while the update still succeeded, is retried by the next launch or the next hermes update, including the “already up to date” path.

When it won’t help

Takeaways