fix(hindsight): skip local_embedded daemon when running as root

PostgreSQL's initdb refuses to run as root, so the embedded Hindsight
daemon could never initialize its data directory under root. The
daemon-start thread would fail, retry, and loop forever — each cycle
reloading embedding models (~958MB RAM, ~33% CPU) with no user-visible
error, leaving Hermes sluggish on a common VPS/cloud root setup.

initialize() now detects root (os.geteuid() == 0) before spawning the
daemon thread, disables local_embedded mode, and surfaces a clear
warning to both the log and the terminal so the user knows to run as a
non-root user or switch to cloud / local_external mode.

Closes #13125.

Co-authored-by: teknium1 <127238744+teknium1@users.noreply.github.com>
This commit is contained in:
LehaoLin 2026-06-21 11:28:02 -07:00 committed by Teknium
parent d0de4601d2
commit 7bc6f18062
2 changed files with 119 additions and 0 deletions

View file

@ -36,6 +36,7 @@ import json
import logging
import os
import queue
import sys
import threading
from datetime import datetime, timezone
@ -1322,6 +1323,30 @@ class HindsightMemoryProvider(MemoryProvider):
# doesn't block the chat. Redirect stdout/stderr to a log file to
# prevent rich startup output from spamming the terminal.
if self._mode == "local_embedded":
# PostgreSQL's initdb refuses to run as root by design, so the
# embedded daemon can never initialize its data directory under
# root. Without this guard the daemon-start thread would fail,
# retry, and loop forever — each cycle reloading embedding models
# (~958MB RAM, ~33% CPU) with no user-visible error. Detect root
# up front and skip daemon startup with a clear message instead.
if hasattr(os, "geteuid") and os.geteuid() == 0:
msg = (
"Hindsight local_embedded mode cannot run as root "
"(PostgreSQL initdb refuses root). Skipping the embedded "
"memory daemon. Run Hermes as a non-root user, or switch "
"to cloud / local_external mode via 'hermes memory setup'."
)
logger.warning(msg)
# Surface to the terminal too — a daemon that never starts
# would otherwise fail silently and the user would only see
# Hermes get sluggish. (issue #13125)
try:
print(f"{msg}", file=sys.stderr, flush=True)
except Exception:
pass
self._mode = "disabled"
return
def _start_daemon():
import traceback
log_dir = get_hermes_home() / "logs"