{"record":{"id":"a76b07be25a1371c","repo":"slopus/happy","slug":"daemon-uninstallation-requires-sudo-privileges-pl","errorCode":null,"errorMessage":"Daemon uninstallation requires sudo privileges. Please run with sudo.","messagePattern":"Daemon uninstallation requires sudo privileges\\. Please run with sudo\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/happy-cli/src/daemon/uninstall.ts","lineNumber":10,"sourceCode":"import { logger } from '@/ui/logger';\nimport { uninstall as uninstallMac } from './mac/uninstall';\n\nexport async function uninstall(): Promise<void> {\n    if (process.platform !== 'darwin') {\n        throw new Error('Daemon uninstallation is currently only supported on macOS');\n    }\n    \n    if (process.getuid && process.getuid() !== 0) {\n        throw new Error('Daemon uninstallation requires sudo privileges. Please run with sudo.');\n    }\n    \n    logger.info('Uninstalling Happy CLI daemon for macOS...');\n    await uninstallMac();\n}","sourceCodeStart":1,"sourceCodeEnd":15,"githubUrl":"https://github.com/slopus/happy/blob/b824cd0a4681d41af631a8e422a813873e4455b0/packages/happy-cli/src/daemon/uninstall.ts#L1-L15","documentation":"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.","triggerScenarios":"Calling uninstall() from packages/happy-cli/src/daemon/uninstall.ts without sudo — i.e. process.getuid() exists and returns a value !== 0.","commonSituations":"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.","solutions":["Re-run the command with sudo: `sudo happy daemon uninstall`","Verify with `whoami`/`id -u` that the process actually runs as root inside the elevated context","If sudo is unavailable, manually remove the launchd plist (~/Library/LaunchAgents or /Library/LaunchDaemons) and daemon binary after unloading it with launchctl"],"exampleFix":"// before\nawait uninstall();\n// after\nimport { execSync } from 'child_process';\nif (execSync('id -u').toString().trim() !== '0') {\n  execSync('sudo happy daemon uninstall', { stdio: 'inherit' });\n} else {\n  await uninstall();\n}","handlingStrategy":"validation","validationCode":"if (process.getuid && process.getuid() !== 0) {\n  throw new Error('Run with sudo: `sudo happy daemon uninstall`');\n}","typeGuard":"const isRoot = (): boolean => typeof process.getuid === 'function' && process.getuid() === 0;","tryCatchPattern":null,"preventionTips":["Check `process.getuid() === 0` before invoking any daemon install/uninstall API","Document sudo requirement in scripts and wrappers","Use `sudo -E` when environment variables must survive elevation"],"tags":["permissions","macos","daemon","sudo"],"backgroundTag":"insufficient-privileges","analyzedSha":"b824cd0a4681d41af631a8e422a813873e4455b0","analyzedAt":"2026-08-31T23:12:36.205Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}