BoundaryML/baml · error
toolchain path points at the baml wrapper itself
Error message
toolchain path points at the baml wrapper itself: {}{origin}
Point at the {} binary instead, which is built alongside it. What it means
Self-exec guard: a path selector points at the baml *wrapper* binary instead of the baml-cli toolchain binary that is built alongside it. Because both live in the same directory this is a one-character mistake; without the guard the wrapper would re-resolve the same path selector and exec itself forever (silent fork loop on unix). The check compares the candidate path against env::current_exe().
Solutions
- Change the selector to the baml-cli binary in the same directory as the wrapper
- Or run `baml toolchain use <path-to-baml-cli>` to record the corrected path
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at baml_language/crates/baml/src/main.rs:904 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/87e94feb97fe4ad4.
Report an issue: GitHub.
Appendix: source
Thrown at baml_language/crates/baml/src/main.rs:904
let text = String::from_utf8(output.stdout).ok()?;
let line = text.lines().next()?.trim();
(!line.is_empty()).then(|| line.to_string())
}
/// Refuse to exec the wrapper itself. `baml` and `baml-cli` are built into the
/// same directory, so pointing at the wrapper is a one-character slip; without
/// this it re-resolves the same selector and execs itself forever, silently on
/// unix and as an unbounded process tree everywhere else.
fn reject_self_exec(cli: &Path, origin: &str) -> Result<()> {
let Ok(current) = env::current_exe() else {
return Ok(());
};
let same = match (current.canonicalize(), cli.canonicalize()) {
(Ok(current), Ok(cli)) => current == cli,
_ => current == cli,
};
if same {
return Err(anyhow!(
"toolchain path points at the baml wrapper itself: {}{origin}\nPoint at the {} binary instead, which is built alongside it.",
cli.display(),
cli_exe_name()
));
}
Ok(())
}
/// Check that a path selector points at something runnable. `origin` is a
/// pre-formatted `set by ...` line, or empty when the path came straight from
/// the command line and needs no attribution.
fn verify_path_toolchain(cli: &Path, origin: &str) -> Result<()> {
if cli.is_dir() {
return Err(anyhow!(
"toolchain path is a directory: {}{origin}\nPoint at the {} binary, e.g. {}",
cli.display(),
cli_exe_name(),
cli.join("bin").join(cli_exe_name()).display()View on GitHub (pinned to bd85ce9dee)