BoundaryML/baml · error

failed to replace {} with {}: {}

Error message

failed to replace {} with {}: {}

What it means

After retrying for up to 60 attempts (~15 seconds) to swap the running executable via the Windows self-update path, `replace_running_exe` gives up and reports the last error (or 'timed out' if all retries failed). The swap typically fails because Windows locks the currently running exe file, preventing rename/replace operations.

Source

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

    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),
        }
    }
    Err(anyhow!(
        "failed to replace {} with {}: {}",
        current.display(),
        tmp.display(),
        last_error
            .map(|err| err.to_string())
            .unwrap_or_else(|| "timed out".to_string())
    ))
}

fn write_text_atomic(path: &Path, text: &str) -> Result<()> {
    if let Some(parent) = path.parent() {
        fs::create_dir_all(parent)?;
    }
    let tmp = path.with_extension("tmp");
    fs::write(&tmp, text)?;
    fs::rename(tmp, path)?;
    Ok(())
}

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Ensure no other baml processes are running (check Task Manager) and retry the update.
  2. Run the update from an elevated (Administrator) prompt if baml.exe is in a protected directory.
  3. Temporarily disable antivirus real-time scanning or add an exclusion for baml.exe, then retry.
  4. As a fallback, manually download the new release and replace baml.exe while the old one is not running.
Defensive patterns

Strategy: retry

Try / catch

// Rust
match result {
    Err(e) if e.to_string().contains("failed to replace") => {
        eprintln!("exe swap failed (file locked?): {e}; retry after closing other baml processes or run elevated");
    }
    _ => {}
}

Prevention

When it happens

Trigger: Calling `baml --replace <tmp> <current>` on Windows when the target exe is locked by the OS or another process for the full 15-second retry window; permission denied on the target path.

Common situations: Antivirus or an installer holds a handle to baml.exe; the CLI is running from a protected directory like Program Files without elevation; multiple baml processes are running simultaneously; the file is on a filesystem that disallows renaming a running binary.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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