nikivdev/code · error · anyhow::Error
launchctl bootstrap failed: {}
Error message
launchctl bootstrap failed: {} What it means
install_launch_agent registers the supervisor as a macOS launchd agent by running `launchctl bootstrap <domain> <plist>`. If launchctl exits non-zero, the stderr is surfaced in this error. Typically means the plist is invalid, the service is already bootstrapped, or the domain-target is wrong.
Source
Thrown at src/supervisor.rs:571
let plist_path = launch_agent_plist_path()?;
let log_path = supervisor_log_path().ok();
let plist = launch_agent_plist(socket_path, boot, log_path.as_deref())?;
fs::write(&plist_path, plist)
.with_context(|| format!("failed to write {}", plist_path.display()))?;
let domain = launch_agent_domain();
let target = launch_agent_target();
let _ = Command::new("launchctl")
.args(["bootout", &domain, plist_path.to_string_lossy().as_ref()])
.output();
let output = Command::new("launchctl")
.args(["bootstrap", &domain, plist_path.to_string_lossy().as_ref()])
.output()
.context("failed to bootstrap launch agent")?;
if !output.status.success() {
bail!(
"launchctl bootstrap failed: {}",
String::from_utf8_lossy(&output.stderr)
);
}
let _ = Command::new("launchctl").args(["enable", &target]).output();
let output = Command::new("launchctl")
.args(["kickstart", "-k", &target])
.output()
.context("failed to kickstart launch agent")?;
if !output.status.success() {
bail!(
"launchctl kickstart failed: {}",
String::from_utf8_lossy(&output.stderr)
);
}
View on GitHub (pinned to a747e741ae)
Solutions
- If the agent is already loaded, run `launchctl bootout <domain>/<plist>` first, then retry bootstrap.
- Check the stderr in the error: "already bootstrapped" means skip bootstrap and just kickstart.
- Verify the plist file exists and is valid XML (plutil -lint <plist>).
- Ensure you're in a GUI login session (not plain SSH) or use the correct domain target for your context.
Example fix
// before launchctl bootstrap gui/$UID ~/Library/LaunchAgents/app.myapp.supervisor.plist // Bootstrap failed: 5: Input/output error (already loaded) // after launchctl bootout gui/$UID/app.myapp.supervisor || true launchctl bootstrap gui/$UID ~/Library/LaunchAgents/app.myapp.supervisor.plist
Defensive patterns
Strategy: try-catch
Validate before calling
// preflight on macOS: lint plist and skip if already bootstrapped
import { execSync } from 'node:child_process';
if (process.platform === 'darwin') {
execSync(`plutil -lint ${plistPath}`); // throws if malformed
const loaded = execSync(`launchctl print gui/$(id -u)/${label} 2>&1 || true`).toString();
if (!loaded.includes('Could not find')) {
console.log('Agent already bootstrapped; skipping bootstrap.');
}
} Try / catch
try {
await supervisorInstallLaunchAgent();
} catch (e) {
const msg = String(e);
if (msg.includes('launchctl bootstrap failed')) {
if (msg.includes('already bootstrapped') || msg.includes('Input/output error')) {
console.error('Agent likely already loaded; bootout first then retry.');
}
return;
}
throw e;
} Prevention
- Bootout an existing agent before re-bootstrapping to avoid 'already loaded' failures.
- Validate plists with `plutil -lint` before installing.
- Run launchctl operations from a GUI login session, not bare SSH.
- Generate the plist path/label programmatically and reuse one constant.
When it happens
Trigger: install_launch_agent (called by run and ensure_supervisor_via_launchd) on macOS when launchctl bootstrap returns non-zero — e.g. "Bootstrap failed: 5: Input/output error" or "Operation already in progress" because the agent is already loaded.
Common situations: Re-running bootstrap when the agent is already loaded (launchctl requires bootout first); malformed or stale plist path; missing GUI domain (running in an SSH session without a user GUI domain); macOS sandbox/permission issues.
Related errors
- launchctl kickstart failed: {}
- codex skill-eval launchd install failed: {}
- Refusing to disable Apple service '{}'. This could break you
- Failed to disable service: {}
- Failed to enable service: {}
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/d4fcdb2317db94cb.
Report an issue: GitHub.