Skip to content

Paseo kit: worktree-root bounce kills only the Paseo 0.7.0 CLI, leaving the daemon orphaned and the supervisor looping #449

Closed

Description

@basiliskus

The Paseo kit's worktree-root bounce doesn't restart the daemon on Paseo 0.7.0. It orphans the running daemon, and the supervisor loop then fails every ~6 seconds for the life of the sandbox. The new worktrees.root is never applied.

Cause. paseo-agent-shim bounces the daemon by killing every process matching pgrep -f "paseo daemon start" except the supervisor loop. On Paseo 0.7.0, paseo daemon start --foreground is only a CLI parent: it spawns processes titled Paseo Supervisor and Paseo Daemon, which don't match that pattern. The kill ends the CLI and leaves both children running. The supervisor loop then relaunches paseo daemon start, which refuses because the old daemon still holds the lock.

Process tree in a running sandbox (Paseo 0.7.0, kit at a1822c3):

sh -c while :; do … paseo daemon start --foreground …   (supervisor:paseo-daemon)
└─ node …/paseo daemon start --foreground --listen 0.0.0.0:6767 --web-ui
   └─ Paseo Supervisor
      └─ Paseo Daemon

Evidence (~/.local/state/paseo/paseo-daemon.log in an acq + msb 0.7.3 sandbox created 2026-09-28):

Terminated
[supervisor] paseo daemon exited; restarting in 5s
[supervisor] starting paseo daemon at 2026-09-28T16:23:47Z
Another Paseo daemon is already running (PID 1546, started 2026-09-28T16:18:38.371Z)
[supervisor] paseo daemon exited; restarting in 5s

The log recorded 6,903 starts and 6,899 "Another Paseo daemon is already running" failures over about 12 hours, all naming the original PID. A second sandbox with the same kit, where no bounce happened, has one start and no failures.

Impact. The worktree root the shim just wrote is never loaded, because the original daemon keeps running on its old config. The loop spins and grows the log indefinitely, and the supervisor never actually supervises the running daemon.

Suggested fix. Stop the daemon through Paseo instead of by process name, e.g. paseo daemon stop, and let the supervisor loop start it again with the kit's flags. That recovered the loop in the sandbox above: after paseo daemon stop, the loop's next paseo daemon start --foreground owned the daemon again. Avoid paseo daemon restart, which relaunches without the kit's --listen/--web-ui flags. Alternatively, kill the CLI's whole process group. A regression check could assert that after a bounce the Paseo Daemon process is a descendant of the supervisor loop and the log has no new "Another Paseo daemon" lines.

Activity

  1. wz-gsa commented on Sep 29, 2026

    @wz-gsa
    Contributor

    This is very likely already fixed, unreleased, in #439 — worth linking before anyone duplicates the fix

    AI-assisted, advisory (OpenCode). Cross-checked this report against an open, unrelated-looking PR and independently live-verified the connection before posting — not just citing it.

    The repro here is against Paseo 0.7.0 and the pre-#439 kit code. #439 (feat(paseo): bump pinned Paseo CLI to 0.9.1, currently open, not yet merged) rewrites the exact code path this issue is about, for an unrelated reason (the version bump), and the rewrite happens to retire the failure mechanism described here:

    • Old code (still on main today, what this issue's repro is running): pgrep -f "paseo daemon start" to find and kill the daemon child, relying on the supervisor loop to relaunch it.
    • feat(paseo): bump pinned Paseo CLI to 0.10.2 #439's new code: tries paseo daemon restart --home ... --timeout 30 first (a real subcommand Paseo 0.9 ships for exactly this), and only falls back to a scoped kill — now matching paseo daemon run, 0.9's actual foreground-daemon invocation — if that command fails.

    Verified live, not just by reading the diff. I installed the real @getpaseo/cli@0.9.1 from npm and reproduced both sides:

    1. Confirmed why the old pattern fails exactly as this issue describes: on the real binary, the daemon process is literally named Paseo Supervisor → Paseo Daemon at the OS level — neither carries paseo daemon start in argv once spawned, so pgrep -f "paseo daemon start" matches nothing, and the kill loop kills zero processes. That leaves the original daemon running and holding the lock while a new one tries to start under it — which is exactly your log's "Another Paseo daemon is already running (PID 1546)" pattern, repeating.
    2. Ran feat(paseo): bump pinned Paseo CLI to 0.10.2 #439's fix directly: paseo daemon restart cleanly swapped the worker PID while explicitly keeping the same supervisor PID. Then separately reproduced the fallback: started paseo daemon run, confirmed pgrep -f "paseo daemon run" correctly matches the real outer PID on 0.9.1 (unlike the old pattern against 0.7.0's processes), killed only that matched PID, and confirmed the entire process tree (daemon + worker) died cleanly with no orphan — the specific defect in this issue does not reproduce against feat(paseo): bump pinned Paseo CLI to 0.10.2 #439's code.

    Net: once #439 merges and ships, this specific bounce-orphans-the-daemon failure should already be closed as a side effect of the version bump's own daemon-lifecycle rewrite — not because #439 was written with this issue in mind (it predates this issue), but because both land on the same root cause (pgrep pattern doesn't match the real 0.9.x process tree) from different directions.

    Recommendation: hold off on writing a separate fix for the pgrep pattern here. After #439 merges, re-run your repro against the new kit code (or I'm happy to) to confirm the fix actually closes this in practice rather than just in theory — I only tested the mechanism in isolation, not your exact end-to-end sandbox scenario. If for some reason #439 stalls, the same fix (swap daemon start/daemon restart semantics) is worth lifting out on its own regardless of the version bump, since it's the real root cause either way.

    Cross-referenced on #439 for visibility in both directions.

  2. added theissue type on Oct 1, 2026
  3. mogul commented on Oct 3, 2026

    @mogul
    Contributor

    Obsoleted by changed behavior of the Paseo daemon in more recent versions, which the kit provides.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions