BigPizzaV3/CodexPlusPlus · error

Codex CLI 路径指向的是目录而不是可执行文件:

Error message

Codex CLI 路径指向的是目录而不是可执行文件:{executable}
请去掉结尾的路径分隔符,或补上具体的可执行文件名。

What it means

validate_codex_executable detects that the configured Codex CLI path exists but is a directory rather than a file, and throws this error before spawn. This commonly happens when a trailing slash or a path to an install directory is entered instead of the full path to the executable.

Solutions

  1. Remove the trailing path separator and append the executable name (e.g. /opt/codex/bin/codex)
  2. Use `which codex` / `where codex` to get the exact executable path
  3. On macOS desktop installs use the full bundle path /Applications/ChatGPT.app/Contents/Resources/codex

Example fix

// before
AppServerConfig { executable: "/Applications/ChatGPT.app/Contents/Resources/".into(), .. }
// after
AppServerConfig { executable: "/Applications/ChatGPT.app/Contents/Resources/codex".into(), .. }
Defensive patterns

Strategy: validation

Validate before calling

use std::path::Path;
fn is_regular_file(executable: &str) -> bool {
    let p = Path::new(executable);
    p.is_file()
}

Try / catch

match CodexAppServer::start(config).await {
    Err(e) if e.to_string().contains("目录而不是可执行文件") => {
        eprintln!("Executable points at a directory; append the binary name");
        // e.g. join("codex") onto the directory and retry
    }
    r => r?,
}

Prevention

When it happens

Trigger: CodexAppServer::start with executable set to a directory path (e.g. "/usr/local/bin/" or "/opt/codex/") — the path.exists() check passes but path.is_dir() triggers the bail.

Common situations: Copy-pasting a folder path from a file manager with trailing separator, entering the npm install directory instead of the bin symlink inside it, assuming the app bundle root is the binary.

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19). Data as JSON: /api/errors/269aecf2855fe4e4. Report an issue: GitHub.

Appendix: source

Thrown at crates/codex-plus-core/src/connect/app_server.rs:77

///
/// 裸命令名(codex)交给 PATH 解析,这里只校验看起来像路径的输入。
fn validate_codex_executable(executable: &str) -> anyhow::Result<()> {
    let looks_like_path = executable.contains('/')
        || executable.contains('\\')
        || Path::new(executable).is_absolute();
    if !looks_like_path {
        return Ok(());
    }
    let path = Path::new(executable);
    if !path.exists() {
        bail!(
            "Codex CLI 路径不存在:{executable}\n请填 Codex CLI 可执行文件的完整路径。\
             macOS 桌面版通常在 /Applications/ChatGPT.app/Contents/Resources/codex;\
             npm 全局安装可用 `which codex` / `where codex` 查看。"
        );
    }
    if path.is_dir() {
        bail!(
            "Codex CLI 路径指向的是目录而不是可执行文件:{executable}\n\
             请去掉结尾的路径分隔符,或补上具体的可执行文件名。"
        );
    }
    #[cfg(unix)]
    {
        use std::os::unix::fs::PermissionsExt;
        if let Ok(metadata) = std::fs::metadata(path)
            && metadata.permissions().mode() & 0o111 == 0
        {
            bail!("Codex CLI 没有执行权限:{executable}");
        }
    }
    Ok(())
}

impl CodexAppServer {
    pub async fn start(config: AppServerConfig) -> anyhow::Result<Self> {

View on GitHub (pinned to b1ed92e5e4)