BoundaryML/baml · error
invalid Span range: start ({start}) > end ({end})
Error message
invalid Span range: start ({start}) > end ({end}) What it means
A Span (file location range) failed to deserialize because the encoded start offset is greater than the end offset. Spans are (file_id, start, end) triples serialized with borsh; TextRange::new would panic on end < start, so the deserializer converts the malformed envelope into a clean std::io error with ErrorKind::InvalidData instead of crashing the thread. This means the serialized data was corrupt, truncated, or produced by an incompatible writer.
Source
Thrown at baml_language/crates/baml_base/src/core_types.rs:117
fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
BorshSerialize::serialize(&self.file_id, writer)?;
let start: u32 = self.range.start().into();
let end: u32 = self.range.end().into();
BorshSerialize::serialize(&start, writer)?;
BorshSerialize::serialize(&end, writer)?;
Ok(())
}
}
impl BorshDeserialize for Span {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
let file_id = FileId::deserialize_reader(reader)?;
let start = u32::deserialize_reader(reader)?;
let end = u32::deserialize_reader(reader)?;
// `TextRange::new` panics on `end < start`. A malformed envelope
// should surface as a clean borsh error rather than a thread crash.
if start > end {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("invalid Span range: start ({start}) > end ({end})"),
));
}
Ok(Span {
file_id,
range: TextRange::new(TextSize::new(start), TextSize::new(end)),
})
}
}
impl Default for Span {
/// Creates a sentinel span that doesn't refer to any real file.
///
/// Uses `u32::MAX` as the file ID to avoid conflicts with real files.
fn default() -> Self {
Self::fake()
}View on GitHub (pinned to bd85ce9dee)
Solutions
- Delete the stale cache/index artifact that is being deserialized and regenerate it.
- Verify the reader is positioned at the correct offset in the stream so fields are not read shifted (file_id, start, end).
- Ensure producer and consumer use the same version of the Span serialization format.
- Validate the source data ranges (start <= end) before serializing Spans.
Example fix
// before: blindly trust cached spans
let span = Span::deserialize_reader(&mut reader)?;
// after: tolerate corrupt caches by rebuilding
let span = Span::deserialize_reader(&mut reader)
.map_err(|e| { fs::remove_file(&cache_path).ok(); e })?; Defensive patterns
Strategy: validation
Validate before calling
// validate before serializing / after deserializing
fn valid_span(start: u32, end: u32) -> bool { start <= end } Type guard
fn is_valid_span(s: &Span) -> bool { s.start <= s.end } Try / catch
match Span::deserialize_reader(&mut reader) {
Ok(span) => span,
Err(e) if e.kind() == std::io::ErrorKind::InvalidData => {
// rebuild/regenerate the corrupted artifact
regenerate(&path)?
}
Err(e) => return Err(e.into()),
} Prevention
- Validate start <= end before serializing any span.
- Never hand-edit binary cache artifacts.
- Regenerate caches after upgrading the library version.
- Read streams at verified offsets with length-prefixed records.
When it happens
Trigger: Calling Span::deserialize_reader (e.g. while loading a persisted index, cache, or IPC payload) on bytes where the u32 start field exceeds the u32 end field.
Common situations: Stale or hand-edited cache files from an older BAML version with a different serialization layout; byte-order/offset desync when reading a concatenated stream at the wrong position; corrupted incremental-compilation artifacts.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- body record omitted log metadata
- baml.json.deserialize failed: {e:?}
- {0}
- value metadata omitted codec
- value metadata omitted availability
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/ea143eff220fcd0d.
Report an issue: GitHub.