The web UI build in Hermes Agent v0.22.5 reached Vite and stopped there. The installer log's last two lines from that process were vite v8.2.4 building client environment for production... and transforming.... The node process then exited 137. dmesg recorded a global OOM kill of pid 1634, node-MainThread, with total-vm:11299164kB, anon-rss:593212kB, and file-rss:3072kB. MemTotal on the guest was 984,552 kB. SwapTotal was 0.
hermes --version after that exited 0. It printed Hermes Agent v0.22.5 (2026.9.24), channel stable, git bf0203a794a0, Python 3.14.9, and OpenAI SDK 2.24.0. /usr/bin/time -v recorded a maximum resident set of 60,956 kB and a wall time of 0:03.19. ls on hermes_cli/web_dist returned No such file or directory. du -B1 -s on ~/.hermes was 2,475,204,608 bytes.
The guest was Ubuntu 24.04.5, kernel 6.8.0-147-generic, glibc 2.39, qemu -m 1024 -smp 1. The installer was install.sh, sha256 abf338605dae6dd28d101673ac6aed7995c955745db46d47676bc591a7957209, run as --channel stable --non-interactive --skip-browser --skip-computer-use. The log said it was installing the latest stable release, v0.22.5. git then checked out bf0203a794, which is the tag v0.22.5 on NousResearch/hermes-agent. GitHub lists that repository's license as MIT.
| On this guest | |
|---|---|
| Version | v0.22.5, bf0203a794, Python 3.14.9, node v26.12.1 |
| Web build | Vite 8.2.4, transforming..., node exit 137 |
| Heap cap | web_build_limits({}) returned --max-old-space-size=4096 |
| Kill | anon-rss:593212kB, total-vm:11299164kB, global OOM |
| Guest | MemTotal 984,552 kB, SwapTotal 0 |
| Disk | ~/.hermes 2,475,204,608 bytes |
hermes --version | exit 0, max RSS 60,956 kB, wall 0:03.19 |
hermes doctor | exit 1, max RSS 410,964 kB, wall 0:51.26 |
hermes -z | exit 2, providers none connected |
| Listen | 127.0.0.1:43095 after that prompt. Before it, ssh and the stub resolver |

Why does the web build ask for 4096 MB?
The installer's web step goes through hermes_cli/source_build.py, which calls apply_web_build_limits. That function copies the environment and, when NODE_OPTIONS has no --max-old-space-size, appends one. The ceiling lives in hermes_cli/web_build_limits.py at this commit. _MIN_WEB_BUILD_HEAP_MB is 1024. _MAX_WEB_BUILD_HEAP_MB is 4096. _cgroup_memory_limit_mb opens /sys/fs/cgroup/memory.max and /sys/fs/cgroup/memory/memory.limit_in_bytes. A missing file, or a file whose text is max, comes back as no limit, and no limit means the ceiling.
def _bounded_heap_mb() -> int:
limit_mb = _cgroup_memory_limit_mb()
if not limit_mb:
return _MAX_WEB_BUILD_HEAP_MB
return max(_MIN_WEB_BUILD_HEAP_MB, min(_MAX_WEB_BUILD_HEAP_MB, int(limit_mb * 0.75)))I imported web_build_limits with the checkout's Python 3.14.9 and called it on an empty env. _cgroup_memory_limit_mb() returned None. _bounded_heap_mb() returned 4096. web_build_limits({}) returned NODE_OPTIONS set to --max-old-space-size=4096 and RAYON_NUM_THREADS set to 1. /sys/fs/cgroup/user.slice/memory.max exists and contains the word max. The function reads the two paths above, and on this guest both opens raised ENOENT. The same node binary, asked for os.totalmem() floored to MiB, printed 961. MemTotal is 984,552 KiB.
scripts/build/web.mjs repeats the 1024 floor, the 4096 ceiling, and those two paths. If NODE_OPTIONS already carries the flag, its re-exec returns immediately. While the build was running, pid 1634 was the only node process, and ps --ppid 1634 listed no children. That is what web.mjs does when the flag is already in the environment: the re-exec returns and Vite runs in the same process. The kill landed before I could read /proc/1634/environ. The flag web_build_limits({}) returns on this guest is --max-old-space-size=4096.
While pid 1634 was still running I read /proc/1634/status. VmRSS was 585,808 kB, VmSize was 11,296,604 kB, the state was running, and the thread count was 12. MemAvailable was 18,436 kB. ps showed kswapd0 at 47.0% CPU. SSH banner exchanges to the guest timed out through that stretch. The first MemAvailable after the kill was 559,160 kB, and the banner came back. The comment in web_build_limits.py says this build can freeze SSH on a small host. The banner timeouts match that comment. 4096 MB of 1024 KiB is 4,194,304 kB, set against a MemTotal of 984,552 kB. The kernel line was constraint=CONSTRAINT_NONE and global_oom. The cgroup files this helper treats as the limit were absent, so the ceiling it picked sits above the RAM the kernel actually had.

What did the installer finish around that kill?
uv 0.13.5 came down as uv 0.13.5 (x86_64-unknown-linux-gnu). Python 3.14.9 installed in 2.64 seconds. The log then marked the TUI built, started the web UI, and wrote the two Vite lines. The failure line names scripts/build/web.mjs and ends exited 137. The following warning says the next launch or hermes update retries the build. After that the log says Install complete! [detached @ bf0203a794] and app products or command publication failed.
~/.local/bin/hermes is a 73-byte shell script. It execs the checkout's own hermes wrapper. PATH in the non-login shell I used was the stock Ubuntu list, and ~/.local/bin was absent from it. With that directory added, --version exited 0.
du -B1 -s on the top-level directories inside ~/.hermes printed 1,034,362,880 for hermes-agent, 1,030,623,232 for tools, 307,617,792 for cache, 418,668,544 for installs, and 4,022,272 for skills. Those five numbers add up to more than the parent's 2,475,204,608, so some files are linked into more than one directory. Inside tools, ffmpeg-9.0.1-linux-x64 is 458,805,248 bytes, python-3.14.9+20261021-linux-x64 is 268,472,320, and node-26.12.1-linux-x64 is 240,324,608. --skip-browser and --skip-computer-use were both on the command. The Vite build still ran. hermes doctor later printed agent-browser not installed and computer_use (system dependency not met), the two pieces those flags skip. The dashboard bundle is the step that exited 137.
What does a prompt do when no provider is connected?
model.default is anthropic/claude-opus-4.6. model.provider is auto. model.base_url is https://openrouter.ai/api/v1. That base URL is the one OpenRouter pricing called with the header left off and with a fake bearer token. Both of those calls came back HTTP 401. This guest sent no completion.
~/.hermes/.env is 28,180 bytes. I listed every assignment whose name contains KEY, TOKEN, SECRET, or PASSWORD. The filter printed no names. _PROVIDER_ENV_HINTS in hermes_cli/doctor.py holds 29 strings. _has_provider_env_config returns true when any of those strings occurs anywhere in the file text:
def _has_provider_env_config(content: str) -> bool:
"""Return True when ~/.hermes/.env contains provider auth/base URL settings."""
from hermes_cli.doctor import _PROVIDER_ENV_HINTS
return any(key in content for key in _PROVIDER_ENV_HINTS)Fifteen of the 29 strings occur in this .env, and every hit sits on a line whose first non-whitespace character is #. OPENROUTER_API_KEY is one of the fifteen. hermes doctor still printed a check beside API key or custom endpoint configured. In the same run it printed OpenRouter API (not configured). Exit status was 1. /usr/bin/time -v recorded a maximum resident set of 410,964 kB and a wall time of 0:51.26. The summary said it found 3 issues, and the first one says to run hermes setup for API keys.
Before any prompt, hermes status said the model was anthropic/claude-opus-4.6, the provider was Auto, providers were none connected, and the gateway was stopped. ss -lnt showed ssh and the stub resolver.

hermes -z with the text reply with the single word pong exited 2. Stdout said Hermes is not connected to any AI provider yet, named hermes model, /login, and hermes auth add, and named OPENROUTER_API_KEY in ~/.hermes/.env. The next line said the request was not processed.
The command left a process behind. The command line is python3 -m hermes_cli.main --profile default gateway run --quiet --idle-exit, pid 4213, parent pid 1. It listened on 127.0.0.1:43095. A minute later the resident set was 219,692 kB. hermes gateway status said the gateway was running manually, and the parenthetical on the next line says it is not a system service. hermes status then showed the gateway running, with providers still none connected. hermes dashboard --status, run before this prompt, said no dashboard or serve process was running. The help text for hermes dashboard names port 9119. 43095 is the port this gateway bound.
config.yaml has no unmanaged_idle_exit_seconds key. The checkout default in hermes_cli/config_defaults.py is 600. The process was started with --idle-exit, and the comment on spawn_unmanaged_gateway says a daemon started that way ends itself once idle. Status printed while pid 4213 was still in the process list.
AgentGateway on a $5 VPS is a process on a guest of this size. It listened on 127.0.0.1:4000 and answered two model names from local mocks, with the provider key in a file on that machine. This Hermes file left base_url on https://openrouter.ai/api/v1 for the whole run.
What does the README's $5 VPS line meet here?
The project README says to run Hermes on a $5 VPS. RackNerd's specials page lists a 1 GB KVM VPS, 1 vCPU, 20 GB SSD, at $21.99 a year. Divided by 12, that is 1.8325, which is $1.83 a month. This guest was qemu -m 1024 -smp 1. The disk image is 40,483,942,400 bytes. The special's disk figure is 20 GB SSD, and ~/.hermes at 2,475,204,608 bytes fits in that figure. The number the kernel ran out of is RAM. MemTotal was 984,552 kB, SwapTotal was 0, node anon-rss was 593,212 kB, and the heap cap the script computed was 4,194,304 kB.
Questions people ask about Hermes on a 1 GB guest
Does the CLI come up if the web build exits 137?
hermes --version exited 0 at 60,956 kB. hermes doctor exited 1 at 410,964 kB and printed its summary. ls of hermes_cli/web_dist still returned No such file or directory after version, doctor, and the prompt. The installer had already printed app products or command publication failed and Install complete! [detached @ bf0203a794].
Why is the cap 4096 MB on a machine with 961 MB of RAM?
_cgroup_memory_limit_mb() returned None, so _bounded_heap_mb() returned 4096, the ceiling. The floor in that function is 1024 MB, for the case where a limit exists and 75% of it is under 1024. This guest took the missing-file branch. web_build_limits({}) printed --max-old-space-size=4096.
Why did doctor mark an API key as configured?
_has_provider_env_config searches the raw .env text for 29 hint strings. Fifteen of those strings appear on comment lines in the 28,180 byte file, including OPENROUTER_API_KEY. The same doctor run printed OpenRouter API (not configured). hermes -z exited 2, and hermes status said providers were none connected.
What listens after install?
Before the prompt, ss showed ssh and the stub resolver. hermes dashboard --status said no dashboard or serve process was running, and the help text names dashboard port 9119. After hermes -z, pid 4213 listened on 127.0.0.1:43095 with --idle-exit. hermes gateway status called that process a manual gateway.
Does the $21.99 special change the heap number?
The special's RAM line is 1 GB, the same size as this qemu -m 1024 guest, where those two cgroup files were missing and the probe printed 4096. The special's disk line is 20 GB SSD. This ~/.hermes tree is 2,475,204,608 bytes.
