BoundaryML/baml · error · EngineError
A function call with ID {call_id} is already in progress
Error message
A function call with ID {call_id} is already in progress What it means
A call was registered with a CallId that the engine already has an in-progress call for. CallIds are expected to be unique per concurrent invocation; a duplicate means the caller is reusing an ID while the original call has not completed.
Source
Thrown at baml_language/crates/bex_engine/src/lib.rs:855
/// BAML `int` is `i64`, so the signal carries the full value; the
/// caller clamps into its shell's range (typically 0..=255 on Unix).
#[error("baml.sys.exit({code})")]
Exit { code: i64 },
#[error("Cannot convert object of type {type_name}")]
CannotConvert { type_name: String },
#[error("Type mismatch: {message}")]
TypeMismatch { message: String },
#[error("Schema inconsistency: {message}")]
SchemaInconsistency { message: String },
#[cfg(feature = "heap_debug")]
#[error("Snapshot not possible for type: {type_name}")]
CannotSnapshot { type_name: String },
#[error("A function call with ID {call_id} is already in progress")]
DuplicateCallId { call_id: CallId },
#[error("Package initialization failed: {0}")]
InitFailed(String),
#[error("{0}")]
Other(String),
}
fn format_vm_internal_error(
err: &bex_vm::errors::VmInternalError,
trace: &[bex_vm::StackFrame],
) -> String {
use std::fmt::Write;
let mut out = bex_vm::format_traceback(
trace
.iter()
.map(|f| (f.file_path.as_str(), f.error_line, f.function_name.as_str())),View on GitHub (pinned to bd85ce9dee)
Solutions
- Generate a fresh unique CallId for each invocation (e.g. UUID)
- Wait for the original call with that ID to finish before reusing it
- On retry-after-failure, allocate a new ID instead of reusing the failed one
- Track and clear call IDs in a registry when calls complete
Example fix
// before call_engine(call_id) // reused id // after let call_id = Uuid::new_v4().to_string(); call_engine(call_id)
Defensive patterns
Strategy: validation
Validate before calling
let mut active: HashSet<CallId> = HashSet::new(); let call_id = Uuid::new_v4().to_string(); assert!(active.insert(call_id.clone()), "call id already in progress");
Try / catch
match result {
Err(EngineError::DuplicateCallId { call_id }) => {
let fresh = Uuid::new_v4().to_string();
retry_with_id(fresh)?;
}
Ok(v) => use(v),
Err(e) => handle(e),
} Prevention
- Generate a unique ID (UUID) per invocation
- Remove IDs from your tracking set when calls complete
- Never reuse an ID across retries without checking completion
When it happens
Trigger: Host code starting a BAML function call with an ID it already used for a still-active call (e.g. retrying without generating a fresh ID, or reentrant invocation with a cached ID).
Common situations: Client code implementing its own call tracking/retries; resuming streams after errors without rotating the call ID; concurrent requests generated from the same ID seed.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- -32801
- timed out waiting for install lock {}
- dynamic-impl table lock poisoned
- Engine lock poisoned
- call_id {0} is already in use by an active call
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/d907f741102b2b50.
Report an issue: GitHub.