slopus/happy · error

Daemon uninstallation requires sudo privileges. Please run w

Error message

Daemon uninstallation requires sudo privileges. Please run with sudo.

What it means

The happy CLI daemon uninstall flow only supports macOS and refuses to remove system-level daemon files without root. Uninstalling deletes launchd plists and daemon binaries owned by root, so the process verifies the effective UID is 0 before proceeding. If getuid() returns a non-zero value, uninstall() throws immediately before touching the filesystem.

Source

Thrown at packages/happy-cli/src/daemon/uninstall.ts:10

import { logger } from '@/ui/logger';
import { uninstall as uninstallMac } from './mac/uninstall';

export async function uninstall(): Promise<void> {
    if (process.platform !== 'darwin') {
        throw new Error('Daemon uninstallation is currently only supported on macOS');
    }
    
    if (process.getuid && process.getuid() !== 0) {
        throw new Error('Daemon uninstallation requires sudo privileges. Please run with sudo.');
    }
    
    logger.info('Uninstalling Happy CLI daemon for macOS...');
    await uninstallMac();
}

View on GitHub (pinned to b824cd0a46)

Solutions

  1. Re-run the command with sudo: `sudo happy daemon uninstall`
  2. Verify with `whoami`/`id -u` that the process actually runs as root inside the elevated context
  3. If sudo is unavailable, manually remove the launchd plist (~/Library/LaunchAgents or /Library/LaunchDaemons) and daemon binary after unloading it with launchctl

Example fix

// before
await uninstall();
// after
import { execSync } from 'child_process';
if (execSync('id -u').toString().trim() !== '0') {
  execSync('sudo happy daemon uninstall', { stdio: 'inherit' });
} else {
  await uninstall();
}
Defensive patterns

Strategy: validation

Validate before calling

if (process.getuid && process.getuid() !== 0) {
  throw new Error('Run with sudo: `sudo happy daemon uninstall`');
}

Type guard

const isRoot = (): boolean => typeof process.getuid === 'function' && process.getuid() === 0;

Prevention

When it happens

Trigger: Calling uninstall() from packages/happy-cli/src/daemon/uninstall.ts without sudo — i.e. process.getuid() exists and returns a value !== 0.

Common situations: A developer runs `happy daemon uninstall` (or equivalent API call) in a regular terminal without elevation on macOS; often after installing the daemon originally with sudo, so removal needs the same privileges.

Related errors


AI-assisted analysis of slopus/happy@b824cd0a46 (2026-08-31). Data as JSON: /api/errors/a76b07be25a1371c. Report an issue: GitHub.