{"record":{"id":"041377e3449f3643","repo":"BoundaryML/baml","slug":"history-boundary-omitted-run-started-record","errorCode":null,"errorMessage":"history boundary {} omitted run started record","messagePattern":"history boundary (.+?) omitted run started record","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"baml_language/crates/bex_events/src/history/mod.rs","lineNumber":405,"sourceCode":"                \"historyValueTornTail\",\n                format!(\n                    \"Value segment {} ended with a torn trailing record; complete prefix was retained\",\n                    segment.label\n                ),\n            ));\n        }\n        for record in parsed.records {\n            match record {\n                ValueFileRecord::RunStarted(record) => started = Some(record),\n                ValueFileRecord::RunCompleted(record) => completed = Some(record),\n                ValueFileRecord::LogEvent(record) => logs.push(record),\n                ValueFileRecord::CaptureLoss(record) => capture_losses.push(record),\n            }\n        }\n    }\n\n    let started = started.ok_or_else(|| {\n        io::Error::new(\n            io::ErrorKind::InvalidData,\n            format!(\n                \"history boundary {} omitted run started record\",\n                fallback_dir\n                    .map(|dir| dir.display().to_string())\n                    .unwrap_or_else(|| \"byte segments\".to_string())\n            ),\n        )\n    })?;\n    let boundary_id =\n        boundary_id_from_header_or_fallback(fallback_dir, &header_boundary_ids, &started)?;\n\n    diagnostics.extend(\n        capture_losses\n            .into_iter()\n            .map(capture_loss_replay_diagnostic),\n    );\n    // Segments are read thread-major; replay in event order so payload ids","sourceCodeStart":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bex_events/src/history/mod.rs#L387-L423","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Verify the boundary directory contains the segment holding the run-started record; restore it if deleted.","Re-record the session if the writer crashed before flushing the run-start record.","Check you are opening the correct boundary directory, not a fragment of one.","Treat the message's dir (or \"byte segments\") hint to locate which input was incomplete."],"exampleFix":"// before\nlet b = open_boundary_from_segments(&dir, &segs)?;\n// after\nif !segs.iter().any(has_run_started) {\n    eprintln!(\"boundary {} incomplete: no run-start record\", dir.display());\n    return Err(ReplayError::Incomplete);\n}\nlet b = open_boundary_from_segments(&dir, &segs)?;","handlingStrategy":"validation","validationCode":"if !segments.iter().any(|r| matches!(r, ValueFileRecord::RunStarted(_))) {\n    return Err(\"boundary segments missing run-started record\".into());\n}","typeGuard":"fn has_run_started(r: &ValueFileRecord) -> bool {\n    matches!(r, ValueFileRecord::RunStarted(_))\n}","tryCatchPattern":"match open_boundary_from_segments(Some(&dir), &segments) {\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidData => {\n        Err(ReplayError::IncompleteBoundary(dir.clone()))\n    }\n    other => other,\n}","preventionTips":["Copy boundary directories atomically and completely, never partially.","Ensure the writer flushes the run-start record before the process can exit.","Validate segment sets for a run-started record before replaying."],"tags":["io","invalid-data","history","replay"],"backgroundTag":"schema-validation-failed","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"}