MemPalace/mempalace · warning · DaemonError
daemon is not running
Error message
daemon is not running
What it means
DaemonError from ensure_client (mempalace/daemon.py:1380): no running daemon was found (get_client_if_running returned None) and the caller passed auto_start=False, so startup is explicitly disallowed. This is the deliberate 'daemon must already be up' contract for callers that never want to spawn a process (e.g. read-only or ephemeral contexts).
Source
Thrown at mempalace/daemon.py:1380
pass
raise
finally:
if lock_fh is not None:
try:
lock_fh.close()
except Exception: # noqa: BLE001 - cleanup best-effort
pass
def ensure_client(
palace_path: str, *, backend: str | None = None, auto_start: bool = True
) -> DaemonClient:
palace_path = canonical_palace_path(palace_path)
client = get_client_if_running(palace_path)
if client is not None:
return client
if not auto_start:
raise DaemonError("daemon is not running")
return start_daemon(palace_path, backend=backend)
def submit_job(
kind: str,
payload: dict[str, Any],
*,
palace_path: str | None = None,
backend: str | None = None,
dedupe_key: str | None = None,
priority: int = 0,
wait: bool = True,
auto_start: bool = False,
timeout: float = DEFAULT_WAIT_TIMEOUT,
stop_on_lock_deferral: bool = False,
) -> dict[str, Any]:
# Strictly opt-in: callers that want the daemon auto-started must say so
# explicitly (the CLI --daemon path passes auto_start=True). The defaultView on GitHub (pinned to 06cb6987f0)
Solutions
- Start the daemon first (start_daemon or ensure_client with auto_start=True), then retry.
- If spawning is intentionally forbidden, catch DaemonError and take the documented fallback (direct write path) rather than retrying.
- Check why a daemon you expected to be running is not: pid file, endpoint.json, daemon log.
Example fix
# before
client = ensure_client(palace_path, auto_start=False) # raises
# after
client = get_client_if_running(palace_path)
if client is None:
client = ensure_client(palace_path, auto_start=True) Defensive patterns
Strategy: fallback
Validate before calling
from mempalace.daemon import get_client_if_running client = get_client_if_running(palace_path) # None, never raises, when not running
Try / catch
from mempalace.daemon import DaemonError
try:
client = ensure_client(palace_path, auto_start=False)
except DaemonError:
client = None # take the direct-write / no-daemon path by design Prevention
- When auto_start=False, always pair the call with a None/DaemonError fallback path.
- Use get_client_if_running for opportunistic daemon usage.
- Don't retry auto_start=False calls in a loop — the daemon won't appear on its own.
When it happens
Trigger: Calling ensure_client(palace_path, auto_start=False) before any daemon exists; the daemon died between discovery and this call leaving no live endpoint; hook runs in an environment where spawning is forbidden.
Common situations: Read-only tools that opportunistically use the daemon when present; hooks configured to fall back to direct writes instead of starting a daemon; sandboxes that block subprocess spawning.
Related errors
- daemon token not found for {palace_path}
- writable daemon startup refused: another writer owns local b
- daemon endpoint missing port
- daemon endpoint pid is not alive
- daemon exited during startup with code {proc.returncode}
AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15).
Data as JSON: /api/errors/8af6c58a81e18005.
Report an issue: GitHub.