{"record":{"id":"9bd5e7f668144f9d","repo":"BoundaryML/baml","slug":"call-id-mismatch","errorCode":null,"errorMessage":"Call ID mismatch: {} != {}","messagePattern":"Call ID mismatch: (.+?) != (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-runtime/src/tracing/mod.rs","lineNumber":507,"sourceCode":"    #[cfg(target_arch = \"wasm32\")]\n    pub(crate) async fn finish_call(\n        &self,\n        call: TracingCall,\n        ctx: &RuntimeContextManager,\n        response: Option<BamlValue>,\n    ) -> Result<uuid::Uuid> {\n        let guard = self.trace_stats.guard();\n\n        let Some((call_id, event_chain, tags)) = ctx.exit() else {\n            anyhow::bail!(\n                \"Attempting to finish a call {:#?} without first starting one. Current context {:#?}\",\n                call,\n                ctx\n            );\n        };\n\n        if call.call_id != call_id {\n            anyhow::bail!(\"Call ID mismatch: {} != {}\", call.call_id, call_id);\n        }\n\n        if let Some(tracer) = &self.tracer {\n            tracer\n                .submit(response.to_log_schema(&self.options, event_chain, tags, call))\n                .await?;\n            guard.done();\n            Ok(call_id)\n        } else {\n            guard.done();\n            Ok(call_id)\n        }\n    }\n\n    // For non-LLM function calls -- used by FFI boundary like with @trace in python\n    #[cfg(not(target_arch = \"wasm32\"))]\n    pub(crate) fn finish_call(\n        &self,","sourceCodeStart":489,"sourceCodeEnd":525,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-runtime/src/tracing/mod.rs#L489-L525","documentation":"In `finish_call` (tracing/mod.rs:507), the call_id popped from the context via `ctx.exit()` does not match `call.call_id`. BAML correlates a finished call with the context entry it started under; a mismatch means the call being finished does not correspond to the active traced call, so the runtime bails to avoid attributing results to the wrong trace.","triggerScenarios":"Two interleaved traced calls sharing one RuntimeContextManager — finishing call A pops call B's id; a `TracingCall` struct cloned/reused across contexts; finishing calls out of the order they were started.","commonSituations":"Concurrent BAML function invocations sharing a context manager in async code; reusing a TracingCall after its first finish; mixed nested function calls where the wrong TracingCall handle is passed to finish_call.","solutions":["Use a dedicated RuntimeContextManager (or proper context stack) per concurrent call so ids stay paired.","Do not reuse a TracingCall after finishing it; create a fresh call per invocation.","Check that the same TracingCall passed to start_call is passed to finish_call.","Serialize start/finish pairs if calls share a context, or finish them in LIFO order."],"exampleFix":"// before: shared context across concurrent calls\nlet ctx = RuntimeContextManager::new();\ntokio::join!(finish(a, &ctx), finish(b, &ctx));\n// after: one context per call\nlet ctx_a = RuntimeContextManager::new();\nlet ctx_b = RuntimeContextManager::new();\ntokio::join!(finish(a, &ctx_a), finish(b, &ctx_b));","handlingStrategy":"validation","validationCode":"// verify pairing before finishing\nassert_eq!(call.call_id, active_call_id_of(&ctx), \"TracingCall/context mismatch\");","typeGuard":null,"tryCatchPattern":"if let Err(e) = runtime.finish_call(call, &ctx, response) {\n    if e.to_string().contains(\"Call ID mismatch\") {\n        log::error!(\"crossed trace calls; isolate contexts per invocation: {e}\");\n    } else {\n        return Err(e);\n    }\n}","preventionTips":["One RuntimeContextManager per concurrent BAML invocation.","Pass the identical TracingCall used at start to finish.","Never reuse TracingCall instances after finishing.","Finish calls in LIFO order when nesting on shared contexts."],"tags":["tracing","state","correlation"],"backgroundTag":"internal-invariant-violation","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}