Hero client commands should suggest --root when only the root-scoped daemon socket exists #151

Open
opened 2026-04-28 06:28:07 +00:00 by mahmoud · 2 comments
Owner

Split out from #135.

Symptom

After starting mycelium with service_mycelium start --root on a fresh machine (root-scoped install), running the client without --root fails with a generic socket-missing error pointing at internal source:

~> mycelium address
Error: nu::shell::error
  × Socket not found: /home/driver/hero/var/sockets/mycelium/rpc.sock
  | Is the service running?
     ╭─[/home/.../tools/modules/openrpc.nu:56:20]
  55 │     if not $exists {
  56 │         error make {msg: $"Socket not found: ($socket)\nIs the service running?"}
     ╰────

~> mycelium address --root
4e6c:db67:6815:dbb0:6177:174b:fcc1:1ae5

The service is running — just under root. The error message doesn't say so, and the operator has to guess that --root is the answer (or read the source).

Why this is a problem

Hero supports two scopes for nearly every service: the user's own daemon (sockets under $HOME/hero/var/sockets/...) and the root-scoped one (/root/hero/var/sockets/...). Most service commands accept --root to switch scope. When a user runs the client without --root but only a root-scoped daemon is up, the client checks the user-scoped socket, finds it missing, and raises the generic openrpc "Socket not found" error.

This is a class of problem — same trap exists for proc, router, proxy, and any future client that uses openrpc_call. The error originates deep inside tools/modules/openrpc.nu, so it can't easily distinguish "daemon not running anywhere" from "daemon only running with the other scope".

Suggested fix

Move the diagnostic from openrpc_call (which is correctly scope-agnostic and shouldn't grow scope-aware fallbacks) up one level into each client wrapper (tools/modules/clients/mycelium.nu, proc.nu, router.nu, proxy.nu).

Before making the call, when running without --root:

  • If the user-scoped socket is missing and the root-scoped socket exists → error with: mycelium daemon is running under root but not under your user. Try: mycelium <subcommand> --root.
  • If neither exists → keep the current generic error (or surface a service_mycelium start hint).

A shared helper in tools/modules/clients/mod.nu (something like client_resolve_socket name root returning the scoped path and asserting clean error text on miss) would let all four clients pick this up without duplication.

Files

  • tools/modules/openrpc.nu:55-57 — current generic socket-missing error.
  • tools/modules/clients/mycelium.nu, proc.nu, router.nu, proxy.nu — sites that resolve socket paths from the --root flag.
  • tools/modules/clients/mod.nu — natural home for a shared client_resolve_socket helper.
Split out from #135. ## Symptom After starting mycelium with `service_mycelium start --root` on a fresh machine (root-scoped install), running the client without `--root` fails with a generic socket-missing error pointing at internal source: ``` ~> mycelium address Error: nu::shell::error × Socket not found: /home/driver/hero/var/sockets/mycelium/rpc.sock | Is the service running? ╭─[/home/.../tools/modules/openrpc.nu:56:20] 55 │ if not $exists { 56 │ error make {msg: $"Socket not found: ($socket)\nIs the service running?"} ╰──── ~> mycelium address --root 4e6c:db67:6815:dbb0:6177:174b:fcc1:1ae5 ``` The service *is* running — just under root. The error message doesn't say so, and the operator has to guess that `--root` is the answer (or read the source). ## Why this is a problem Hero supports two scopes for nearly every service: the user's own daemon (sockets under `$HOME/hero/var/sockets/...`) and the root-scoped one (`/root/hero/var/sockets/...`). Most service commands accept `--root` to switch scope. When a user runs the client without `--root` but only a root-scoped daemon is up, the client checks the user-scoped socket, finds it missing, and raises the generic openrpc "Socket not found" error. This is a class of problem — same trap exists for `proc`, `router`, `proxy`, and any future client that uses `openrpc_call`. The error originates deep inside `tools/modules/openrpc.nu`, so it can't easily distinguish "daemon not running anywhere" from "daemon only running with the other scope". ## Suggested fix Move the diagnostic from `openrpc_call` (which is correctly scope-agnostic and shouldn't grow scope-aware fallbacks) **up one level** into each client wrapper (`tools/modules/clients/mycelium.nu`, `proc.nu`, `router.nu`, `proxy.nu`). Before making the call, when running without `--root`: - If the user-scoped socket is missing **and** the root-scoped socket exists → error with: `mycelium daemon is running under root but not under your user. Try: mycelium <subcommand> --root`. - If neither exists → keep the current generic error (or surface a `service_mycelium start` hint). A shared helper in `tools/modules/clients/mod.nu` (something like `client_resolve_socket name root` returning the scoped path *and* asserting clean error text on miss) would let all four clients pick this up without duplication. ## Files - `tools/modules/openrpc.nu:55-57` — current generic socket-missing error. - `tools/modules/clients/mycelium.nu`, `proc.nu`, `router.nu`, `proxy.nu` — sites that resolve socket paths from the `--root` flag. - `tools/modules/clients/mod.nu` — natural home for a shared `client_resolve_socket` helper.
Author
Owner

Picking this up. Planned scope:

  • Add client_check_socket helper in tools/modules/clients/mod.nu. When the user-scoped socket is missing, it sudo test -e's the root-scoped socket and throws either did you mean --root? (root daemon up) or try service_<name> start (neither up). Reuses the existing openrpc_needs_sudo from tools/modules/openrpc.nu.
  • Call the helper from each <prefix>_call in the five client wrappers — mycelium, proc, router, proxy, codescalers (the issue body said four, but codescalers.nu follows the same pattern; including it for consistency).
  • Trim the now-redundant Is the service running? line from openrpc.nu — the wrapper owns that messaging now. openrpc_call itself stays scope-agnostic per the issue's recommendation.

No behaviour change when commands succeed; only the failure UX is improved. PR will follow.

Picking this up. Planned scope: - Add `client_check_socket` helper in `tools/modules/clients/mod.nu`. When the user-scoped socket is missing, it `sudo test -e`'s the root-scoped socket and throws either *did you mean `--root`?* (root daemon up) or *try `service_<name> start`* (neither up). Reuses the existing `openrpc_needs_sudo` from `tools/modules/openrpc.nu`. - Call the helper from each `<prefix>_call` in the five client wrappers — `mycelium`, `proc`, `router`, `proxy`, **`codescalers`** (the issue body said four, but `codescalers.nu` follows the same pattern; including it for consistency). - Trim the now-redundant `Is the service running?` line from `openrpc.nu` — the wrapper owns that messaging now. `openrpc_call` itself stays scope-agnostic per the issue's recommendation. No behaviour change when commands succeed; only the failure UX is improved. PR will follow.
mahmoud self-assigned this 2026-04-28 09:37:59 +00:00
mahmoud added this to the ACTIVE project 2026-04-28 09:38:01 +00:00
mahmoud added this to the now milestone 2026-04-28 09:38:03 +00:00
Author
Owner

PR #161 ready for review. Live-tested on kristof6mycelium address now produces the new --root hint, mycelium address --root is unchanged.

PR #161 ready for review. Live-tested on `kristof6` — `mycelium address` now produces the new `--root` hint, `mycelium address --root` is unchanged.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_skills#151
No description provided.