nikivdev/code · error

codex skill-eval launchd install failed: {}

Error message

codex skill-eval launchd install failed: {}

What it means

Flow installs a launchd job for the codex skill-eval daemon by shelling out to a helper installer binary (with FLOW_CODEX_SKILL_EVAL_F_BIN pointing at the current executable). If that subprocess exits with a non-zero status, Flow bubbles up its trimmed stderr with this error.

Source

Thrown at src/ai.rs:9621

        .arg(script)
        .arg("install")
        .arg("--minutes")
        .arg(minutes.to_string())
        .arg("--limit")
        .arg(limit.to_string())
        .arg("--max-targets")
        .arg(max_targets.to_string())
        .arg("--within-hours")
        .arg(within_hours.to_string());
    if dry_run {
        command.arg("--dry-run");
    }
    command.env("FLOW_CODEX_SKILL_EVAL_F_BIN", current_exe);
    let output = command
        .output()
        .context("failed to run codex skill-eval launchd installer")?;
    if !output.status.success() {
        bail!(
            "codex skill-eval launchd install failed: {}",
            String::from_utf8_lossy(&output.stderr).trim()
        );
    }
    Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
}

fn codex_enable_global(
    dry_run: bool,
    install_launchd: bool,
    start_daemon: bool,
    sync_skills: bool,
    full: bool,
    minutes: usize,
    limit: usize,
    max_targets: usize,
    within_hours: u64,
    provider: Provider,

View on GitHub (pinned to a747e741ae)

Solutions

  1. Read the stderr text embedded in the error — it is the installer's own message and names the concrete failure.
  2. Re-run the installer manually (the same command Flow invokes, with FLOW_CODEX_SKILL_EVAL_F_BIN set) to see full output.
  3. Ensure ~/Library/LaunchAgents exists and is writable, and that launchctl is available (run inside a GUI session, not a bare SSH context).
  4. Reinstall/update Flow so the installer helper matches the current version, then retry `f codex enable-global`.

Example fix

// before
$ f codex enable-global
Error: codex skill-eval launchd install failed: launchctl: could not bootstrap domain

// after: fix environment, then verify
$ mkdir -p ~/Library/LaunchAgents
$ launchctl print gui/$(id -u) >/dev/null  # confirm launchd domain accessible
$ f codex enable-global
Defensive patterns

Strategy: try-catch

Validate before calling

use std::path::Path;
// preflight before install:
let agents_dir = dirs::home_dir().map(|h| h.join("Library/LaunchAgents"));
let writable = agents_dir
    .as_deref()
    .map(std::path::Path::is_dir)
    .unwrap_or(false);
assert!(writable, "~/Library/LaunchAgents must exist and be writable");

Try / catch

match result {
    Err(e) if e.to_string().contains("codex skill-eval launchd install failed") => {
        // e.to_string() embeds the installer's stderr; log it and inspect
        // ~/Library/LaunchAgents permissions and launchctl availability before retrying.
        eprintln!("launchd install failed: {e}");
    }
    Err(e) => return Err(e),
    Ok(out) => println!("installed: {out}"),
}

Prevention

When it happens

Trigger: Running `f codex enable-global` (or install-launchd / full setup) when the launchd installer subprocess fails — e.g. it cannot write to ~/Library/LaunchAgents, launchctl rejects the plist, or the installer binary itself errors.

Common situations: macOS permission issues (LaunchAgents directory not writable or protected), malformed plist due to unusual HOME, an outdated or mismatched installer binary after a Flow upgrade, launchctl failing in non-GUI/SSH sessions where the user's launchd domain is unavailable.

Related errors


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