BoundaryML/baml · error · io::Error
history boundary {} was not begun
Error message
history boundary {} was not begun What it means
append_log_body requires that a history boundary was previously begun with the given BoundaryId. The boundaries map holds per-boundary state; if the ID is absent, an io::Error of kind NotFound is produced saying the boundary was not begun. It surfaces as a NotFound error from append_log_body.
Source
Thrown at baml_language/crates/bex_events/src/history/mod.rs:180
writer,
},
);
Ok(())
}
pub fn append_log_body(
&self,
boundary_id: BoundaryId,
event: LogEventRecord,
codec: ValueCodec,
body: Vec<u8>,
) -> io::Result<ValueWriteOutcome> {
let mut inner = self
.inner
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
let state = inner.boundaries.get_mut(&boundary_id).ok_or_else(|| {
io::Error::new(
io::ErrorKind::NotFound,
format!(
"history boundary {} was not begun",
boundary_id.to_wire_string()
),
)
})?;
state.writer.append_log_body(event, codec, body)
}
pub fn append_capture_loss(
&self,
boundary_id: BoundaryId,
record: &CaptureLossRecord,
) -> io::Result<()> {
let mut inner = self
.inner
.lock()View on GitHub (pinned to bd85ce9dee)
Solutions
- Call begin_boundary (or the boundary-opening API) before append_log_body and reuse the returned BoundaryId.
- Ensure the same History instance that began the boundary is used for appends.
- Synchronize threads so begin completes before any append on that boundary.
- Check the ID's wire string in the message against registered boundaries to spot ID mix-ups.
Example fix
// before history.append_log_body(boundary_id, record)?; // after let boundary_id = history.begin_boundary(&run_started)?; history.append_log_body(boundary_id, record)?;
Defensive patterns
Strategy: validation
Validate before calling
if !begun_boundaries.contains(&boundary_id) {
return Err("append_log_body called before begin_boundary".into());
} Try / catch
match history.append_log_body(boundary_id, record) {
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
let id = history.begin_boundary(&run_started)?;
history.append_log_body(id, record)?
}
other => other?,
} Prevention
- Always call begin_boundary before any append and thread the returned ID.
- Keep boundary IDs with the owning History instance; never share IDs across instances.
- In multi-threaded writers, begin the boundary before spawning appenders.
When it happens
Trigger: Calling append_log_body(boundary_id, ...) with a BoundaryId that was never created via begin_boundary, or one that came from a different History instance/thread.
Common situations: Race between threads where logs are appended before the boundary-start call completes; reusing a stale boundary ID after a History was recreated; ordering bugs in test harnesses (e.g. replay_orders_logs_chronologically_across_threads) that append before begin.
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
- history boundary {} was not found
- failed to read value segment {}: {error}
- history boundary {} omitted run started record
- history boundary {} has inconsistent value segment boundary
- history boundary for project {} omitted canonical boundary i
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/4c5b94ce887890f6.
Report an issue: GitHub.