BoundaryML/baml · error · io::Error

history boundary {} has inconsistent value segment boundary

Error message

history boundary {} has inconsistent value segment boundary ids

What it means

boundary_id_from_header_or_fallback collects the boundary IDs stored in each .bamlvalue header; if they disagree (headers were written by different boundary sessions), it returns InvalidData instead of guessing. This detects mixed or interleaved segment files from multiple runs in one directory.

Source

Thrown at baml_language/crates/bex_events/src/history/mod.rs:613

        RunStatus::Cancelled => (None, None, completed.cancellation),
        RunStatus::Pending
        | RunStatus::Running
        | RunStatus::WaitingForInput
        | RunStatus::WaitingForEnv
        | RunStatus::Cancelling => (None, None, None),
    }
}

fn boundary_id_from_header_or_fallback(
    fallback_dir: Option<&Path>,
    header_boundary_ids: &[BoundaryId],
    started: &RunStartedRecord,
) -> io::Result<BoundaryId> {
    if let Some(first) = header_boundary_ids.first().copied() {
        if header_boundary_ids.iter().all(|id| *id == first) {
            return Ok(first);
        }
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!(
                "history boundary {} has inconsistent value segment boundary ids",
                fallback_dir
                    .map(|dir| dir.display().to_string())
                    .unwrap_or_else(|| "byte segments".to_string())
            ),
        ));
    }
    fallback_dir
        .and_then(boundary_id_from_dir_name)
        .ok_or_else(|| {
            io::Error::new(
                io::ErrorKind::InvalidData,
                format!(
                    "history boundary for project {} omitted canonical boundary id",
                    started.request.project_id.0
                ),

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Clean the boundary directory and re-record so all segments come from one run.
  2. Remove segment files whose header boundary ID differs from the run you want to replay.
  3. Give each recording session its own unique directory.
  4. Inspect .bamlvalue headers to identify which segments belong to which run.

Example fix

// before
// segments from two runs share one dir
let id = boundary_id_from_header_or_fallback(&segs, Some(&dir), &started)?;
// after
segs.retain(|s| s.header_boundary_id == expected_id);
let id = boundary_id_from_header_or_fallback(&segs, Some(&dir), &started)?;
Defensive patterns

Strategy: validation

Validate before calling

let ids: std::collections::HashSet<_> =
    segments.iter().map(|s| s.header_boundary_id).collect();
if ids.len() > 1 {
    return Err(format!("mixed boundary ids in {}: {ids:?}", dir.display()));
}

Try / catch

match open_boundary_from_segments(Some(&dir), &segments) {
    Err(e) if e.kind() == std::io::ErrorKind::InvalidData => {
        log::error!("{} mixes runs; re-record", dir.display());
        Err(e)
    }
    other => other,
}

Prevention

When it happens

Trigger: Opening a boundary whose segment files' headers contain differing BoundaryIds — e.g. two recording runs wrote into the same directory, or segment files from one run were copied into another's directory.

Common situations: Reusing a temp/history directory across test runs without cleaning it; merging history directories manually; a clock/ordering bug causing two writers to share a dir.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/f6260a2391442d87. Report an issue: GitHub.