MemPalace/mempalace · error · DaemonError
daemon token not found for {palace_path}
Error message
daemon token not found for {palace_path} What it means
DaemonError from read_token() (mempalace/daemon.py:162): it tries to read the shared-secret token file at <state_dir>/token and re-raises any OSError (missing file, permission denied, unreadable) as DaemonError. The token is the bearer credential DaemonClient sends for HTTP auth, so without it the daemon cannot be used from this client.
Source
Thrown at mempalace/daemon.py:162
def ensure_token(palace_path: str) -> str:
token_path = state_dir(palace_path) / "token"
if token_path.exists():
token = token_path.read_text(encoding="utf-8").strip()
if token:
return token
token = secrets.token_urlsafe(32)
_write_private(token_path, token + "\n")
return token
def read_token(palace_path: str) -> str:
token_path = state_dir(palace_path) / "token"
try:
return token_path.read_text(encoding="utf-8").strip()
except OSError as exc:
raise DaemonError(f"daemon token not found for {palace_path}") from exc
def endpoint_path(palace_path: str) -> Path:
return state_dir(palace_path) / "endpoint.json"
def pid_path(palace_path: str) -> Path:
return state_dir(palace_path) / "pid"
def queue_path(palace_path: str) -> Path:
return state_dir(palace_path) / "queue.sqlite3"
def _read_endpoint(palace_path: str) -> dict[str, Any]:
try:
with open(endpoint_path(palace_path), encoding="utf-8") as fh:
return json.load(fh)View on GitHub (pinned to 06cb6987f0)
Solutions
- Start the daemon first with start_daemon(palace_path) (or ensure_client with auto_start=True) so ensure_token creates the token.
- Verify the token file exists and is readable: ls -l <state_dir>/token; if permissions are wrong, restart the daemon under the correct user.
- If the state dir was deleted or corrupted, stop any running daemon and let ensure_token regenerate the token.
- Check the state directory path resolution (canonical_palace_path / state_dir) matches between the writer and reader of the token.
Example fix
# before client = DaemonClient(palace_path) # DaemonError if never started # after client = ensure_client(palace_path, auto_start=True) # starts daemon + ensures token
Defensive patterns
Strategy: fallback
Validate before calling
from mempalace import daemon
def token_ready(palace_path: str) -> bool:
return (daemon.state_dir(palace_path) / "token").is_file() Try / catch
from mempalace.daemon import DaemonError, ensure_client
try:
client = DaemonClient(palace_path)
except DaemonError:
client = ensure_client(palace_path, auto_start=True) # start daemon / mint token Prevention
- Always bootstrap daemon usage through ensure_client/start_daemon so ensure_token runs first.
- Run the daemon and its clients as the same OS user.
- Don't delete or move the state directory while a daemon is in use.
When it happens
Trigger: Calling DaemonClient / get_client_if_running before the daemon has ever started (ensure_token hasn't created the file); running the client as a different OS user than the one that started the daemon (0600-perm token file via _write_private); deleting the palace state directory; a read-only or corrupted state dir.
Common situations: First use on a machine where start_daemon was never invoked; mixed-user setups (daemon under your user, hook under another); cleanup scripts that rm -rf the state dir while the daemon still runs; moving the palace directory without its state dir.
Related errors
- daemon endpoint not found
- 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/eea308612708bf19.
Report an issue: GitHub.