BoundaryML/baml · error

usage: baml --replace <tmp> <current>

Error message

usage: baml --replace <tmp> <current>

What it means

This bail occurs in `replace_running_exe`, the Windows-only helper for `baml --replace` used by the self-update feature. It expects exactly two path arguments — the downloaded temporary exe and the current running exe — and rejects any invocation with a different argument count. Since this subcommand is an internal implementation detail of the updater, seeing it means the CLI was invoked manually or the updater passed malformed arguments.

Source

Thrown at baml_language/crates/baml/src/main.rs:1609

}

#[cfg(all(feature = "self-update", not(feature = "no-self-update")))]
fn http_client() -> Result<reqwest::blocking::Client> {
    http_client_with_timeout(HTTP_TIMEOUT)
}

fn http_client_with_timeout(timeout: Duration) -> Result<reqwest::blocking::Client> {
    reqwest::blocking::Client::builder()
        .connect_timeout(timeout.min(Duration::from_secs(10)))
        .timeout(timeout)
        .build()
        .context("failed to build HTTP client")
}

#[cfg(all(windows, feature = "self-update", not(feature = "no-self-update")))]
fn replace_running_exe(args: Vec<String>) -> Result<()> {
    if args.len() != 2 {
        anyhow::bail!("usage: baml --replace <tmp> <current>");
    }
    let tmp = PathBuf::from(&args[0]);
    let current = PathBuf::from(&args[1]);
    let mut last_error = None;
    for _ in 0..60 {
        std::thread::sleep(Duration::from_millis(250));
        match fs::remove_file(&current) {
            Ok(()) => match fs::rename(&tmp, &current) {
                Ok(()) => return Ok(()),
                Err(err) => last_error = Some(err),
            },
            Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
                match fs::rename(&tmp, &current) {
                    Ok(()) => return Ok(()),
                    Err(err) => last_error = Some(err),
                }
            }
            Err(err) => last_error = Some(err),

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Do not invoke `baml --replace` manually; run the normal self-update flow instead.
  2. If calling it programmatically, pass exactly two arguments: `baml --replace <tmp-exe> <current-exe>`.
  3. Reinstall or re-run the updater so it regenerates the correct arguments.

Example fix

// before
baml --replace /tmp/baml-new.exe
// after
baml --replace /tmp/baml-new.exe C:\\Program Files\\baml\\baml.exe
Defensive patterns

Strategy: validation

Validate before calling

if (args.length !== 2) {
  throw new Error('baml --replace requires exactly 2 arguments: <tmp> <current>');
}

Prevention

When it happens

Trigger: Running `baml --replace` with zero, one, or three+ arguments instead of exactly two; calling the internal subcommand directly instead of letting the self-update flow invoke it.

Common situations: A user discovers the hidden `--replace` subcommand and tries it by hand; a broken or partially-downloaded updater shim invokes it with the wrong argv; a wrapper script reorders or drops arguments.

Understand the failure class

Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/600b46e416f6a1b8. Report an issue: GitHub.