nikivdev/code · error
Failed to disable service: {}
Error message
Failed to disable service: {} What it means
disable_service runs an external `launchctl` command and this error is raised when the command exits non-zero; the captured stderr is embedded in the message. It means launchctl itself rejected the disable/bootout operation, not that the tool found no service.
Source
Thrown at src/macos.rs:725
}
}
// Then disable
let target = format!("{}/{}", domain, svc.id);
let mut cmd = if svc.service_type.requires_sudo() {
let mut c = Command::new("sudo");
c.args(["launchctl", "disable", &target]);
c
} else {
let mut c = Command::new("launchctl");
c.args(["disable", &target]);
c
};
let output = cmd.output()?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
bail!("Failed to disable service: {}", stderr);
}
Ok(())
}
/// Enable a launchd service.
fn enable_service(svc: &LaunchdService) -> Result<()> {
let domain = svc.service_type.domain();
// First enable
let target = format!("{}/{}", domain, svc.id);
let mut cmd = if svc.service_type.requires_sudo() {
let mut c = Command::new("sudo");
c.args(["launchctl", "enable", &target]);
c
} else {
let mut c = Command::new("launchctl");
c.args(["enable", &target]);View on GitHub (pinned to a747e741ae)
Solutions
- Read the embedded stderr in the message — it contains launchctl's actual reason.
- Re-run the disable command with sudo if the service lives in the system domain.
- Verify the service is currently loaded: `launchctl print <domain>/<label>`; if already unloaded there is nothing to disable.
- Confirm the plist path and label are correct before retrying.
Example fix
// before flow macos disable my-daemon // fails: not loaded / no sudo // after sudo flow macos disable my-daemon // or ensure service is loaded first
Defensive patterns
Strategy: try-catch
Validate before calling
let loaded = std::process::Command::new("launchctl")
.args(["print", &format!("gui/{}/{}", unsafe { libc::geteuid() }, label)])
.status()
.map(|s| s.success())
.unwrap_or(false);
if !loaded { eprintln!("service not loaded; nothing to disable"); return; } Type guard
fn is_launchctl_stderr(err: &anyhow::Error) -> bool {
err.to_string().starts_with("Failed to disable service: ")
} Try / catch
match macos::run_disable(opts) {
Err(e) if e.to_string().contains("Failed to disable service:") => {
let stderr = e.to_string();
eprintln!("launchctl said: {stderr}");
if stderr.contains("Operation not permitted") { /* rerun with sudo */ }
}
other => other?,
} Prevention
- Always read the stderr embedded in the error message — it is launchctl's own reason.
- Use sudo for services in the system domain.
- Confirm the service is loaded before disabling it.
- Lint the plist with plutil when configs were recently edited.
When it happens
Trigger: launchctl fails to bootout the service: service not currently loaded, wrong domain (user vs system), sudo required but not used, or malformed plist path.
Common situations: Disabling a system-level service without sudo; the service was already unloaded; passing the wrong label/domain so launchctl cannot find the service.
Related errors
- Failed to enable service: {}
- Failed to bootstrap service: {}
- Refusing to disable Apple service '{}'. This could break you
- codex skill-eval launchd install failed: {}
- pbcopy exited with status {}
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/f158c808ee5bed86.
Report an issue: GitHub.