nikivdev/code · error · anyhow::Error

launchctl kickstart failed: {}

Error message

launchctl kickstart failed: {}

What it means

As the final step of install_launch_agent, the code runs `launchctl kickstart -k <target>` to (re)start the freshly bootstrapped launch agent. Non-zero exit from launchctl produces this error with launchctl's stderr. The service label/target was registered but couldn't be started.

Source

Thrown at src/supervisor.rs:584

    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)
        );
    }

    println!(
        "Installed launch agent {} at {}",
        launch_agent_label(),
        plist_path.display()
    );
    Ok(())
}

#[cfg(target_os = "macos")]
fn launch_agent_kickstart() -> Result<()> {
    let target = launch_agent_target();
    let output = Command::new("launchctl")
        .args(["kickstart", "-k", &target])

View on GitHub (pinned to a747e741ae)

Solutions

  1. Check the stderr in this error and run `launchctl print <target>` for detailed launchd state.
  2. Verify the plist's Label matches the kickstart target and the Program/ProgramArguments path exists and is executable.
  3. Run the supervisor binary directly to surface any startup crash, fix it, then kickstart again.
  4. Re-bootstrap the plist after fixing it (bootout then bootstrap) before kicking start.

Example fix

// before
<key>ProgramArguments</key><array><string>/usr/local/bin/myapp-supervisor</string></array>  // binary missing
// after
<key>ProgramArguments</key><array><string>~/.local/bin/myapp</string><string>supervisor</string><string>serve</string></array>  // correct, executable path
Defensive patterns

Strategy: try-catch

Validate before calling

import { execSync, existsSync } from 'node:child_process';
import { statSync } from 'node:fs';
if (process.platform === 'darwin') {
  const bin = '/path/to/myapp'; // ProgramArguments[0] from plist
  if (!existsSync(bin) || !(statSync(bin).mode & 0o111)) {
    throw new Error(`launchd program ${bin} missing or not executable`);
  }
  execSync(`launchctl print gui/$(id -u)/${label} > /dev/null 2>&1`); // must be loaded
}

Try / catch

try {
  await supervisorInstallLaunchAgent();
} catch (e) {
  if (String(e).includes('launchctl kickstart failed')) {
    console.error('kickstart failed: verify plist Label matches target and the program path exists/executable.');
    console.error('Debug with: launchctl print <target>');
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: install_launch_agent on macOS where bootstrap succeeded but kickstart -k fails — usually a bad label in the plist, the plist's program path missing/not executable, or the service immediately exiting so launchctl reports failure.

Common situations: Plist points to a binary path that doesn't exist or lacks +x; mismatch between the kickstart target label and the plist's Label key; launchd job crashes at startup (bad config); macOS permission prompt not granted.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/aaf8dadda86c7e65. Report an issue: GitHub.