BoundaryML/baml · error
Trace publisher channel is closed
Error message
Trace publisher channel is closed
What it means
Raised in publish_trace_event when the mpsc channel to the trace publisher worker is closed (mpsc::error::TrySendError::Closed). It means the publisher background task has already terminated (or was never started), so trace events can no longer be accepted. Any subsequent event submissions will fail until the publisher is restarted.
Source
Thrown at engine/baml-runtime/src/tracingv2/publisher/publisher.rs:1136
)),
}
}
pub fn publish_trace_event(event: Arc<TraceEventWithMeta>) -> anyhow::Result<()> {
let Some(channel) = ensure_publisher_started() else {
return Ok(());
};
match channel.try_send(PublisherMessage::Trace(event)) {
Ok(()) => Ok(()),
Err(mpsc::error::TrySendError::Full(_)) => {
log::warn!(
"Trace event queue is full (max 4 batches). Dropping trace event. \
Consider increasing BAML_TRACE_BATCH_SIZE or reducing trace volume."
);
Ok(())
}
Err(mpsc::error::TrySendError::Closed(_)) => {
Err(anyhow::anyhow!("Trace publisher channel is closed"))
}
}
}
// Note, the library we are using doesnt seem to work well for flushing in Node
// but that's ok since noone uses our wasm build in node for logging.
// https://github.com/whizsid/wasmtimer-rs/issues/26
pub async fn flush() -> anyhow::Result<()> {
log::debug!("Flushing traces [rust]");
// Set a timeout to avoid waiting indefinitely.
let timeout_duration = Duration::from_secs(30);
// First try to flush the trace publisher (which should also flush blobs internally)
let mut publisher_result: Option<anyhow::Result<()>> = None;
if let Some(channel) = ensure_publisher_started() {
let (ack_tx, ack_rx) = tokio::sync::oneshot::channel();
let send_res = channel
.send(PublisherMessage::Flush(ack_tx))View on GitHub (pinned to bd85ce9dee)
Solutions
- Stop publishing events after flush/shutdown; guard call sites with an is-active check.
- Re-initialize/restart the publisher before sending new events.
- Check logs for why the publisher worker exited (panic or fatal API error).
- Ignore or log the error during teardown instead of propagating it as fatal.
Example fix
// before
publisher.publish_trace_event(event)?; // panics/errors after shutdown
// after
if publisher.is_active() {
if let Err(e) = publisher.publish_trace_event(event) {
log::warn!("trace publish skipped: {e}");
}
} Defensive patterns
Strategy: type-guard
Validate before calling
// check publisher state before sending
if !publisher.is_running() {
log::warn!("publisher shut down; dropping trace event");
return;
} Type guard
fn publisher_accepts_events(tx: &mpsc::Sender<Msg>) -> bool { !tx.is_closed() } Try / catch
match publisher.publish_trace_event(ev) {
Err(e) if e.to_string().contains("channel is closed") => {
log::debug!("publisher already shut down; dropping event");
}
Err(e) => log::error!("publish failed: {e}"),
Ok(_) => {}
} Prevention
- Enforce a lifecycle rule: no publishes after flush/shutdown
- Check channel-closed state before submitting events from other threads
- Log (don't propagate) publish failures during teardown
- Watch for worker panics that close the channel early
When it happens
Trigger: Calling publish_trace_event after the publisher task was shut down (flush/shutdown completed, runtime dropped) or after the worker task panicked/exited due to a previous fatal error.
Common situations: Application publishing trace events after calling flush during shutdown, calling publish from a different thread after the runtime was dropped, or a prior unrecoverable error (e.g. auth failure) tearing down the worker.
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
- Blob flush timed out after {:?}
- Flush timed out after {:?}
- BAML engine is shutting down
- Attempting to finish a call without first starting one
- Transport error: {0}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/41e7f1533ddb4d6b.
Report an issue: GitHub.