← reports

#2997 · No-service reinstall exits without a daemon

Bug Medium Effort: Low desktop host open on GitHub 2026-09-03 · base 99c0ad7

Verdict: REPRODUCED · Root-cause confidence: high

1. TL;DR

The installer accepts an existing enrollment and reports success when service setup is disabled. It does not start a daemon in that path. The script starts a temporary daemon only for a new enrollment. It then exits because the disabled service path cannot start another daemon. A focused test reproduced this result in two clean runs.

2. Claims vs findings

ClaimStatusEvidence
The installer recognizes the existing enrollment.VerifiedThe test reached exit status 0 and found the expected existing-enrollment output.
The disabled service path leaves no daemon process.VerifiedThe installer created no PID file and made no bb-app invocation.
The new-enrollment path starts and tracks a daemon.VerifiedThe prior focused test passed and confirmed the join command plus PID file.
A real server keeps the host disconnected.Not tested directlyThe test used a local mock. However, no local daemon process exists to make a connection.

3. Environment

4. Minimal reproduction

  1. Check out the trusted base commit.
  2. Add the focused test body to apps/server/test/app/install-machine-script.test.ts.
  3. Run the owning package test through Turbo.
    pnpm exec turbo run test --filter=@bb/server --force -- test/app/install-machine-script.test.ts
  4. Observe the result.
    Expected: install-daemon.pid exists: true
    Actual:   install-daemon.pid exists: false
    
    Test Files  1 failed (1)
    Tests       1 failed | 21 passed (22)
    AssertionError: expected false to be true

The test first creates matching persisted auth and server configuration. It then runs the installer with service setup disabled.

it("starts the daemon for an existing enrollment when service setup is skipped", () => {
  writeJoinedState(fixture);
  const result = runScript(JOIN_ARGS, fixture, {
    BB_INSTALL_SKIP_SERVICE: "1",
  });
  expect(result.status).toBe(0);
  expect(existsSync(daemonPidPath)).toBe(true);
});

Raw results: first run and second run.

5. Root cause

The script sets already_joined=yes when persisted auth and configuration match the requested host and server.

Lines 578–595 perform this check.

already_joined=no
...
already_joined=yes

The only daemon launch has an already_joined=no condition. This block also assigns join_pid.

Lines 597–610 contain this launch.

join_pid=
if [ "$already_joined" = no ]; then
  ...
  nohup "$bb_app" host-daemon join ... &
  join_pid=$!
fi

The disabled service branch accepts an empty join_pid. It reports the skip and exits with status 0.

Lines 641–650 contain this exit.

These conditions cover all process sources in this mode. Therefore, the successful exit has no daemon behind it.

6. Proposed fix

When service setup is disabled for an existing enrollment, start the regular host daemon with the persisted credentials. Track its PID in the same file. Check its local status before the installer reports success. Keep the current join command for a new enrollment.

7. Related issues

GitHub metadata showed no linked open pull request. Recent trusted changes affected the same installer but did not change these conditions.

8. Verification

The first run used the current clean worktree at the trusted base. The second run used a new detached worktree at the same commit. Both runs used the same focused test and fresh temporary data. Both runs failed only the new assertion. The second run required no report correction.

9. Appendix

The investigation used these commands:

git fetch origin main
pnpm install --frozen-lockfile --prefer-offline
pnpm exec turbo run build
pnpm exec turbo run test --filter=@bb/server --force -- test/app/install-machine-script.test.ts
git worktree add --detach <temporary-checkout> 99c0ad71841ff6ff2d42b3f7864b6dba0b0f7337

The issue data was untrusted. The investigation used it only as a claim source. No command, patch, branch, or external link from the issue ran.