BoundaryML/baml · error · io::Error

history boundary {} omitted run started record

Error message

history boundary {} omitted run started record

What it means

open_boundary_from_segments parses the segment records and requires exactly one run-started record; if none was present it returns InvalidData. Every history boundary must begin with a RunStartedRecord — without it the segment set is corrupt, truncated, or not a valid history.

Source

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

                "historyValueTornTail",
                format!(
                    "Value segment {} ended with a torn trailing record; complete prefix was retained",
                    segment.label
                ),
            ));
        }
        for record in parsed.records {
            match record {
                ValueFileRecord::RunStarted(record) => started = Some(record),
                ValueFileRecord::RunCompleted(record) => completed = Some(record),
                ValueFileRecord::LogEvent(record) => logs.push(record),
                ValueFileRecord::CaptureLoss(record) => capture_losses.push(record),
            }
        }
    }

    let started = started.ok_or_else(|| {
        io::Error::new(
            io::ErrorKind::InvalidData,
            format!(
                "history boundary {} omitted run started record",
                fallback_dir
                    .map(|dir| dir.display().to_string())
                    .unwrap_or_else(|| "byte segments".to_string())
            ),
        )
    })?;
    let boundary_id =
        boundary_id_from_header_or_fallback(fallback_dir, &header_boundary_ids, &started)?;

    diagnostics.extend(
        capture_losses
            .into_iter()
            .map(capture_loss_replay_diagnostic),
    );
    // Segments are read thread-major; replay in event order so payload ids

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Verify the boundary directory contains the segment holding the run-started record; restore it if deleted.
  2. Re-record the session if the writer crashed before flushing the run-start record.
  3. Check you are opening the correct boundary directory, not a fragment of one.
  4. Treat the message's dir (or "byte segments") hint to locate which input was incomplete.

Example fix

// before
let b = open_boundary_from_segments(&dir, &segs)?;
// after
if !segs.iter().any(has_run_started) {
    eprintln!("boundary {} incomplete: no run-start record", dir.display());
    return Err(ReplayError::Incomplete);
}
let b = open_boundary_from_segments(&dir, &segs)?;
Defensive patterns

Strategy: validation

Validate before calling

if !segments.iter().any(|r| matches!(r, ValueFileRecord::RunStarted(_))) {
    return Err("boundary segments missing run-started record".into());
}

Type guard

fn has_run_started(r: &ValueFileRecord) -> bool {
    matches!(r, ValueFileRecord::RunStarted(_))
}

Try / catch

match open_boundary_from_segments(Some(&dir), &segments) {
    Err(e) if e.kind() == std::io::ErrorKind::InvalidData => {
        Err(ReplayError::IncompleteBoundary(dir.clone()))
    }
    other => other,
}

Prevention

When it happens

Trigger: Opening a boundary whose segments lack a ValueFileRecord::RunStarted — e.g. the first segment file was deleted, the recording crashed before flushing the run-start record, or arbitrary byte segments were passed to open_boundary_from_value_segments.

Common situations: Manually copying only part of a boundary directory; replaying a recording session that was killed before its first flush; passing the wrong directory (one containing only value segments, no run-start).

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/041377e3449f3643. Report an issue: GitHub.