#2997 · No-service reinstall exits without a daemon
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
| Claim | Status | Evidence |
|---|---|---|
| The installer recognizes the existing enrollment. | Verified | The test reached exit status 0 and found the expected existing-enrollment output. |
| The disabled service path leaves no daemon process. | Verified | The installer created no PID file and made no bb-app invocation. |
| The new-enrollment path starts and tracks a daemon. | Verified | The prior focused test passed and confirmed the join command plus PID file. |
| A real server keeps the host disconnected. | Not tested directly | The test used a local mock. However, no local daemon process exists to make a connection. |
3. Environment
- Trusted bb commit:
99c0ad71841ff6ff2d42b3f7864b6dba0b0f7337. - Host: macOS Darwin 25.6.0 on arm64.
- Node:
v22.22.3. - Test runner: Vitest 4.1.1 through Turbo 2.8.3.
- The test used temporary data directories and a local mock status server.
- No provider, user runtime, or external server was necessary.
4. Minimal reproduction
- Check out the trusted base commit.
- Add the focused test body to
apps/server/test/app/install-machine-script.test.ts. - Run the owning package test through Turbo.
pnpm exec turbo run test --filter=@bb/server --force -- test/app/install-machine-script.test.ts
- 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.