{"record":{"id":"9a48c8564a6cb530","repo":"BoundaryML/baml","slug":"failed-to-exec-baml-cli-err","errorCode":null,"errorMessage":"failed to exec baml-cli: {err}","messagePattern":"failed to exec baml-cli: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"baml_language/crates/baml/src/main.rs","lineNumber":454,"sourceCode":"    // too would double it up.\n    let channel_warned = warn_if_channel_outdated(&selector, &version);\n    // A cache refresh (due at most once per TTL window) runs in the\n    // background while the command itself runs, instead of stalling it.\n    let refresh = start_lazy_refresh(&selector);\n\n    let mut command = Command::new(cli);\n    command.args(args);\n    command.env(\"BAML_WRAPPER_EXEC\", \"1\");\n    command.env(\"BAML_WRAPPER_RESOLVED_TOOLCHAIN\", &version);\n\n    let Some(refresh) = refresh else {\n        // Common case: nothing to refresh, so the wrapper can hand the\n        // process over entirely.\n        #[cfg(unix)]\n        {\n            use std::os::unix::process::CommandExt;\n            let err = command.exec();\n            return Err(anyhow!(\"failed to exec baml-cli: {err}\"));\n        }\n        #[cfg(not(unix))]\n        {\n            let status = command.status().context(\"failed to run baml-cli\")?;\n            return Ok(status.code().unwrap_or(1));\n        }\n    };\n\n    // Refresh in flight: run the command as a child (exec would kill the\n    // refresh thread), then give the refresh whatever remains of its budget\n    // and surface any warnings the fresh caches newly justify.\n    let status = command.status().context(\"failed to run baml-cli\")?;\n    refresh.wait();\n    if !channel_warned {\n        warn_if_channel_outdated(&selector, &version);\n    }\n    Ok(status.code().unwrap_or(1))\n}","sourceCodeStart":436,"sourceCodeEnd":472,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/baml/src/main.rs#L436-L472","documentation":"On Unix, the `baml` wrapper hands control to the resolved `baml-cli` binary via `Command::exec()`, which only returns on failure. If the exec syscall fails (permission denied, missing binary, bad interpreter, ENOEXEC), the wrapper throws this error wrapping the underlying io::Error.","triggerScenarios":"Calling any pass-through `baml <args>` command where the resolved baml-cli binary cannot be exec'd: file not present despite stale state, non-executable permissions, corrupted install, or a filesystem mounted noexec.","commonSituations":"Interrupted self-update leaving a partial baml-cli, toolchain directory moved/deleted after `use`, copying the install onto a noexec mount (e.g. some /tmp mounts or network shares), or antivirus/quarantine stripping the exec bit.","solutions":["Run `baml self-update` (or reinstall baml) to restore a healthy baml-cli binary.","Check the exec bit on the resolved binary: `chmod +x $(which baml-cli)` or the toolchain path shown in the error.","Verify the binary's filesystem is not mounted noexec: `mount | grep <path>`; remount with exec or relocate the toolchain.","Inspect the wrapped io::Error text in the message (e.g. ENOENT vs EACCES) to target the specific cause."],"exampleFix":"# before (exec fails: missing exec bit)\n$ baml generate\nerror: failed to exec baml-cli: Permission denied (os error 13)\n\n# after\n$ chmod +x ~/.baml/toolchains/0.210.0/bin/baml-cli\n$ baml generate","handlingStrategy":"try-catch","validationCode":"import os, shutil, stat\ndef can_exec_cli():\n    path = shutil.which(\"baml-cli\")\n    if path is None:\n        raise SystemExit(\"baml-cli not found — run `baml self-update` or reinstall\")\n    if not (os.stat(path).st_mode & stat.S_IXUSR):\n        raise SystemExit(f\"baml-cli not executable: {path} — chmod +x\")","typeGuard":"function isExecutableFile(p: string): boolean {\n  try { fs.accessSync(p, fs.constants.X_OK); return fs.statSync(p).isFile(); }\n  catch { return false; }\n}","tryCatchPattern":"result = subprocess.run([\"baml\"] + args, capture_output=True)\nif result.returncode != 0 and \"failed to exec baml-cli\" in result.stderr.decode():\n    # wrapper-level exec failure: reinstall before retrying\n    subprocess.run([\"baml\", \"self-update\"], check=True)","preventionTips":["Don't interrupt `baml self-update`; a partial install breaks exec later.","Keep the baml install on an exec-mounted filesystem (avoid noexec /tmp or NAS).","After copying or restoring backups, re-apply the executable bit.","Read the wrapped io::Error (ENOENT/EACCES/ENOEXEC) to diagnose quickly."],"tags":["exec","process","unix","installation"],"backgroundTag":"exec-failed","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}