nikivdev/code · error
Failed to enable service: {}
Error message
Failed to enable service: {} What it means
enable_service first bootstraps (or, for sudo services, shells out to sudo launchctl bootstrap) to load the launchd service; this error is raised when that first bootstrap command exits non-zero, with launchctl's stderr embedded in the message. It is the load step failing, distinct from the later bootstrap retry at error 685.
Source
Thrown at src/macos.rs:750
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]);
c
};
let output = cmd.output()?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
bail!("Failed to enable service: {}", stderr);
}
// Then bootstrap (load)
let mut cmd = if svc.service_type.requires_sudo() {
let mut c = Command::new("sudo");
c.args(["launchctl", "bootstrap", &domain]);
c.arg(&svc.plist_path);
c
} else {
let mut c = Command::new("launchctl");
c.args(["bootstrap", &domain]);
c.arg(&svc.plist_path);
c
};
let output = cmd.output()?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);View on GitHub (pinned to a747e741ae)
Solutions
- Inspect the stderr embedded in the error for launchctl's exact reason.
- Run the enable command with sudo when the service type requires it.
- Validate the plist: `plutil -lint <path/to/plist>` and confirm the file exists.
- Bootstrap manually to debug: `sudo launchctl bootstrap gui/$(id -u) <plist>`.
Example fix
// before flow macos enable my-daemon // fails: Bootstrap failed: 5: Input/output error // after plutil -lint ~/Library/LaunchAgents/com.example.my-daemon.plist sudo flow macos enable my-daemon
Defensive patterns
Strategy: validation
Validate before calling
let plist = format!("~/Library/LaunchAgents/com.example.{}.plist", label);
let ok = std::process::Command::new("plutil").args(["-lint", &plist]).status().map(|s| s.success()).unwrap_or(false);
if !ok { eprintln!("plist invalid or missing"); return; } Type guard
fn is_bootstrap_failure(err: &anyhow::Error) -> bool {
err.to_string().starts_with("Failed to enable service: ") || err.to_string().starts_with("Failed to bootstrap service: ")
} Try / catch
match macos::run_enable(opts) {
Err(e) if e.to_string().contains("Failed to enable service:") => {
if e.to_string().contains("Operation not permitted") {
// escalate: rerun with sudo
} else {
eprintln!("launchctl: {}", e);
}
}
other => other?,
} Prevention
- Run enable with sudo when the service type requires it.
- Validate plists with `plutil -lint` before enabling.
- Ensure the plist path exists and the label matches the file's Label key.
When it happens
Trigger: Running enable_service for a service whose type requires sudo but is run without it, or launchctl bootstrap fails for reasons like a malformed plist, nonexistent plist path, or wrong domain target.
Common situations: Enabling a system service without sudo; typo in the plist path; plist with XML errors that launchctl rejects.
Related errors
- Failed to disable 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/40d0d11495f6edf3.
Report an issue: GitHub.