BoundaryML/baml · error · BamlSysError
Library already initialized from
Error message
Library already initialized from {existing_path}, cannot change to {requested_path} What it means
baml-sys initializes the native library through a process-wide singleton (once-style init); this error is raised when an init call requests a library path different from the one already loaded. The process cannot have two different native library instances, so the conflicting request is rejected, and both the existing and requested paths are reported.
Solutions
- Initialize baml-sys exactly once at process startup with the final path and reuse it
- Remove duplicate init calls with conflicting paths (search for the init/load call sites)
- Align all components on the same library path (or drop explicit paths to use the default resolution)
- If a different library is genuinely required, load it in a separate process
Example fix
// before
baml_sys::init("/opt/baml/libbaml.so");
// later in another module
baml_sys::init("/usr/lib/libbaml.so"); // panics/errors
// after
baml_sys::init("/opt/baml/libbaml.so"); // single init, shared via OnceLock
Defensive patterns
Strategy: try-catch
Try / catch
static INIT: OnceLock<PathBuf> = OnceLock::new();
fn ensure_init(path: Option<PathBuf>) -> Result<()> {
let p = INIT.get_or_init(|| path.unwrap_or_else(default_path)).clone();
baml_sys::init(&p).map_err(|e| match e {
BamlSysError::AlreadyInitialized { existing_path, .. } if existing_path == p => Ok(()),
BamlSysError::AlreadyInitialized { existing_path, requested_path } => Err(e),
other => Err(other),
}?)
} Prevention
- Wrap initialization in a OnceCell/OnceLock so it runs at most once
- Centralize init in one module; forbid other modules from choosing library paths
- Accept an already-initialized library with the same path as a no-op
- In tests, use a single global init fixture instead of per-test paths
When it happens
Trigger: Calling the init/load API twice with different explicit library paths in the same process, or mixing code paths where one initializes with a system-installed library and another with a downloaded cached one.
Common situations: Test suites where one test sets a custom library path and later tests call the default init, embedding code that configures baml-sys at startup and a dependency that re-initializes with its own path, or hot-reload logic re-running initialization with new arguments.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- {0}
- Checksum mismatch: expected
- Engine not initialized. Call create_baml_runtime first.
- Failed to determine cache directory
- Failed to download library
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/8695ff4bdc86977c.
Report an issue: GitHub.
Appendix: source
Thrown at languages/rust/baml-sys/src/error.rs:57
/// Failed to determine cache directory.
#[error("Failed to determine cache directory: {0}")]
CacheDir(String),
/// Download failed.
#[error("Failed to download library: {0}")]
DownloadFailed(String),
/// Checksum mismatch after download.
#[error("Checksum mismatch: expected {expected}, got {actual}")]
ChecksumMismatch { expected: String, actual: String },
/// IO error.
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
/// Library already initialized with different path.
#[error("Library already initialized from {existing_path}, cannot change to {requested_path}")]
AlreadyInitialized {
existing_path: PathBuf,
requested_path: PathBuf,
},
}
/// Result type for baml-sys operations.
pub type Result<T> = std::result::Result<T, BamlSysError>;
View on GitHub (pinned to bd85ce9dee)