nikivdev/code · error

Flow Codex wrapper is missing at {}; build or sync Flow firs

Error message

Flow Codex wrapper is missing at {}; build or sync Flow first

What it means

Flow manages a global Codex configuration by writing a `codex` table into the user's global config TOML, and it references a wrapper binary (DEFAULT_GLOBAL_CODEX_WRAPPER_BIN) that must exist on disk. Before modifying the config, upsert_global_codex_config verifies the wrapper binary exists; if it does not, it aborts with this error rather than writing a config that points at a nonexistent binary.

Source

Thrown at src/ai.rs:9513

    let temp = parent.join(format!(
        ".{}.tmp-{}-{}",
        path.file_name()
            .and_then(|value| value.to_str())
            .unwrap_or("flow.toml"),
        std::process::id(),
        unix_now_secs()
    ));
    fs::write(&temp, content).with_context(|| format!("failed to write {}", temp.display()))?;
    fs::rename(&temp, path).with_context(|| format!("failed to replace {}", path.display()))?;
    Ok(())
}

fn upsert_global_codex_config(path: &Path) -> Result<(String, bool, bool, bool)> {
    let mut root = parse_global_flow_toml(path)?;
    let created = !path.exists();
    let wrapper_path = config::expand_path(DEFAULT_GLOBAL_CODEX_WRAPPER_BIN);
    if !wrapper_path.exists() {
        bail!(
            "Flow Codex wrapper is missing at {}; build or sync Flow first",
            wrapper_path.display()
        );
    }

    let codex = ensure_toml_table(&mut root, "codex")?;
    codex.insert("runtime_skills".to_string(), TomlValue::Boolean(true));
    codex.insert(
        "auto_resolve_references".to_string(),
        TomlValue::Boolean(true),
    );
    codex
        .entry("home_session_path".to_string())
        .or_insert_with(|| TomlValue::String(DEFAULT_GLOBAL_CODEX_HOME_SESSION_PATH.to_string()));
    codex
        .entry("prompt_context_budget_chars".to_string())
        .or_insert_with(|| TomlValue::Integer(DEFAULT_GLOBAL_CODEX_PROMPT_BUDGET as i64));
    codex

View on GitHub (pinned to a747e741ae)

Solutions

  1. Build or sync Flow so the wrapper binary is produced at the expected path (e.g. run `f codex sync` or rebuild the Flow binary per the README).
  2. Check the path printed in the error message and confirm whether the file exists there (ls the directory).
  3. If Flow was moved or HOME changed, reinstall Flow so expand_path(DEFAULT_GLOBAL_CODEX_WRAPPER_BIN) resolves to the real binary location.

Example fix

// before: running enable-global on a fresh machine
$ f codex enable-global
Error: Flow Codex wrapper is missing at ~/.local/bin/f-codex-wrapper; build or sync Flow first

// after: build/sync Flow first
$ f codex sync   # or: cargo build --release && f codex sync
$ f codex enable-global
Defensive patterns

Strategy: validation

Validate before calling

use std::path::Path;
fn wrapper_exists(expanded_wrapper: &Path) -> bool {
    expanded_wrapper.is_file()
}
// call before running any command that syncs the global codex config:
// assert!(wrapper_exists(&expanded_wrapper_path), "build/sync Flow first");

Type guard

fn is_existing_file(p: &std::path::Path) -> bool {
    p.is_file()
}

Prevention

When it happens

Trigger: Calling any Flow command that upserts the global Codex config (e.g. `f codex enable-global`, `full` setup) when the expanded wrapper path (typically under ~/.local/... or the Flow install dir) does not exist because Flow was never built/synced or the binary was deleted.

Common situations: Fresh machine setup where `f codex sync`/build was skipped; wrapper removed by cleanup scripts or after upgrading the Flow install location; PATH/HOME differences (e.g. running under a different user or CI) making expand_path resolve to a different directory.

Related errors


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