BoundaryML/baml · critical
failed to exec {}: {err}{origin}
Error message
failed to exec {}: {err}{origin} What it means
After `pass_through` resolves a toolchain-specific CLI binary (`cli` path) and attributes it (`origin`), it execs it on Unix. If the exec syscall fails — the binary is missing, not executable, has a broken interpreter/shebang, or lives on a noexec mount — this error is thrown with the binary path, the io::Error, and the origin annotation identifying which toolchain provided it.
Source
Thrown at baml_language/crates/baml/src/main.rs:498
verify_path_toolchain(cli, &origin)?;
reject_self_exec(cli, &origin)?;
let mut command = Command::new(cli);
command.args(args);
command.env("BAML_WRAPPER_EXEC", "1");
// Deliberately not BAML_WRAPPER_RESOLVED_TOOLCHAIN: that carries a version,
// and a local build has none. A separate variable also lets the toolchain
// binary tell the two situations apart, which `baml ide install` needs.
command.env("BAML_WRAPPER_LOCAL_TOOLCHAIN", cli);
// Anything verify_path_toolchain could not rule out (wrong architecture,
// a noexec mount, a missing interpreter) surfaces here, so this message
// carries the attribution too.
#[cfg(unix)]
{
use std::os::unix::process::CommandExt;
let err = command.exec();
Err(anyhow!("failed to exec {}: {err}{origin}", cli.display()))
}
#[cfg(not(unix))]
{
let status = command
.status()
.map_err(|err| anyhow!("failed to run {}: {err}{origin}", cli.display()))?;
Ok(status.code().unwrap_or(1))
}
}
fn active_selector() -> Result<ResolvedSelector> {
if let Ok(value) = env::var("BAML_VERSION") {
if !value.trim().is_empty() {
return Ok(ResolvedSelector {
selector: normalize_selector(value.trim(), &env::current_dir()?),
source: SelectorSource::Env,
});
}View on GitHub (pinned to bd85ce9dee)
Solutions
- Read the `{origin}` suffix to identify which toolchain binary failed, then verify it exists and is executable: `ls -l <path>`.
- Reinstall the offending toolchain: `baml toolchain install <version> --force`.
- Switch to a known-good toolchain: `baml toolchain use canary` or a previously working version.
- Check the filesystem mount for noexec and the binary architecture with `file <path>`.
- Inspect the wrapped io::Error (ENOENT/EACCES/ENOEXEC) to pinpoint whether the path, permissions, or format is the problem.
Example fix
# before (pinned toolchain binary deleted) $ baml generate error: failed to exec /home/u/.baml/toolchains/0.199.0/bin/baml-cli: No such file or directory (os error 2) (pinned via toolchain manifest) # after $ baml toolchain install 0.199.0 --force $ baml generate
Defensive patterns
Strategy: try-catch
Validate before calling
import os, stat, subprocess
def check_toolchain_binary():
out = subprocess.run(["baml", "toolchain", "list"], capture_output=True, text=True)
# confirm the active/pinned toolchain path exists and is executable before dispatch
for line in out.stdout.splitlines():
if line.startswith("*") and "/bin/baml-cli" in line:
p = line.split()[-1]
if not os.path.exists(p):
raise SystemExit(f"active toolchain binary missing: {p} — reinstall with `baml toolchain install --force`")
if not (os.stat(p).st_mode & stat.S_IXUSR):
raise SystemExit(f"not executable: {p}") Type guard
function canExec(p: string): boolean {
try { fs.accessSync(p, fs.constants.X_OK); return true; } catch { return false; }
} Try / catch
result = subprocess.run(["baml"] + args, capture_output=True)
if result.returncode != 0 and "failed to exec" in result.stderr.decode():
msg = result.stderr.decode()
origin = msg.split("(")[-1] # attribution of which toolchain supplied the binary
print(f"Toolchain binary unusable ({origin}); switching to known-good and reinstalling")
subprocess.run(["baml", "toolchain", "use", "canary"], check=True) Prevention
- After deleting/moving a toolchain directory, re-pin or `toolchain use` a valid one immediately.
- When using --manifest-base-url mirrors, verify downloads complete and checksums pass before switching.
- Match toolchain architecture to your host (check with `file <binary>`), especially on Apple Silicon.
- Avoid placing toolchains on noexec mounts; verify with `mount`.
- Keep a known-good toolchain installed as a fallback (`toolchain use canary`).
When it happens
Trigger: Running any `baml` command that dispatches into an active toolchain binary where exec fails: toolchain deleted/moved after pinning, exec bit stripped, corrupted download, incompatible binary for the CPU/OS, or noexec mount.
Common situations: Pinning a toolchain path that was later removed, partial downloads from a custom `--manifest-base-url` mirror, cross-architecture toolchain installs (e.g. x86_64 binary on Apple Silicon without Rosetta), noexec NAS/home mounts, or hardlink/symlink targets deleted.
Related errors
- failed to exec baml-cli: {err}
- toolchain binary is not executable: {}{origin}
- usage: baml toolchain install <canary|nightly|version>
- usage: baml toolchain use <canary|nightly|version|path>
- usage: baml toolchain pin <canary|nightly|version|path>
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/1c2037ecdd73ba40.
Report an issue: GitHub.