BoundaryML/baml · error · anyhow::Error
No call_id found. This indicates a bug in BAML. Please…
Error message
No call_id found. This indicates a bug in BAML. Please report this with a stack trace (RUST_BACKTRACE=1)
What it means
RuntimeContextManager::call_id_stack maintains a stack of active function-call IDs; when allow_empty is false and the stack is empty, it returns this anyhow error stating that no call_id was found and calling it a bug in BAML. It is thrown because code (call_function / stream_function_with_expr_events paths) expects to run inside an active function-call context but the context stack was empty.
Solutions
- Only access ctx.call_id inside an active BAML function call (e.g. inside b.FunctionCall / ctx-manager-managed call scope).
- Pass allow_empty=true (or use the corresponding API) if an empty stack is legitimate for your use case.
- Check for calls from background threads/timers that run after the function call has finished; capture the call_id while the call is live instead.
- If the error fires during a normal b.Test / b.Call with RUST_BACKTRACE=1, report it to the BAML repo as the message requests — it is meant to indicate an internal bug.
Example fix
// before (outside any call) const ids = ctx.manager.getCallStack(); // throws: no call_id found // after (inside a call) await b.Test<MyFn>(/* ... */); // or call within ctx-manager-managed scope, then read ctx.call_id
Defensive patterns
Strategy: try-catch
Validate before calling
// Only call when inside a managed call:
const safeCallStack = (ctx) => {
try { return ctx.manager.getCallStack(false); } catch { return []; }
}; Type guard
const hasActiveCall = (ctx) => {
try { return ctx.manager.getCallStack(true).length > 0; } catch { return false; }
}; Try / catch
try {
const ids = ctx.manager.getCallStack(false);
} catch (e) {
if (String(e).includes('No call_id found')) {
// not inside an active BAML call — reschedule or use allow_empty=true
} else throw e;
} Prevention
- Read ctx.call_id only inside the function-call lifecycle (hooks tied to an active call).
- Capture the call_id synchronously while the call is running; never from deferred/background work.
- Use allow_empty=true when an empty stack is acceptable in your integration.
- Run with RUST_BACKTRACE=1 during development to attribute unexpected occurrences.
When it happens
Trigger: Calling runtime APIs that resolve the current call_id (e.g. ctx.call_id.get_stack(false) from a client hook, or internal calls from call_function / stream_function_with_expr_events) when no function call is currently executing on that context.
Common situations: Accessing ctx.call_id inside an on_create_client / client-side callback or outside b.FunctionCall context; calling the API from a background thread or after the function call completed; Python/TS users reaching into runtime context manager APIs at the wrong lifecycle point.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- assertion failed
- BAML Generate failed - Project has errors.
- baml.json.serialize failed
- baml.json.serialize returned non-string value
- endsWith() method only available on strings at
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/fd6313500a551133.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-runtime/src/types/context_manager.rs:76
// pub fn call_id(&self) -> Result<uuid::Uuid> {
// self.context
// .lock()
// .unwrap()
// .last()
// .map(|(id, ..)| *id)
// .ok_or_else(|| anyhow::anyhow!("No call id found. This indicates a bug in BAML. Please report this with a stack trace (RUST_BACKTRACE=1)"))
// }
pub fn call_id_stack(&self, allow_empty: bool) -> Result<Vec<FunctionCallId>> {
let res: Vec<FunctionCallId> = self
.context
.lock()
.unwrap()
.iter()
.map(|(.., call_id)| call_id.clone())
.collect();
if res.is_empty() && !allow_empty {
Err(anyhow::anyhow!("No call_id found. This indicates a bug in BAML. Please report this with a stack trace (RUST_BACKTRACE=1)"))
} else {
Ok(res)
}
}
pub fn new(baml_src_reader: BamlSrcReader) -> Self {
Self {
baml_src_reader: Arc::new(baml_src_reader),
context: Default::default(),
global_tags: Default::default(),
}
}
pub fn upsert_tags(&self, tags: HashMap<String, BamlValue>) {
let call_id_stack = {
let mut ctx = self.context.lock().unwrap();
if let Some((.., last_tags, _)) = ctx.last_mut() {
last_tags.extend(tags.clone());View on GitHub (pinned to bd85ce9dee)