BoundaryML/baml · error
offset fits in BAML int
Error message
offset fits in BAML int
What it means
Internal invariant panic when parsing a ZonedDateTime: the numeric UTC offset (offset_ns) was already validated to be within ±24h (MAX_TZ_OFFSET_NS), so it must fit in a BAML int (i64-backed). Value::try_int().expect() failing means the earlier bound check was bypassed or corrupted.
Source
Thrown at baml_language/crates/bex_vm/src/package_baml/time.rs:501
(&full[..open], Some(annotation.to_string()))
}
_ => (full, None),
};
let datetime = OffsetDateTime::parse(timestamp, &Rfc3339).map_err(|e| {
parse_error(format!(
"ZonedDateTime.parse: cannot parse {timestamp:?} as an RFC 3339 timestamp \
(zoneless strings belong to PlainDateTime.parse): {e}"
))
})?;
let offset_ns = i64::from(datetime.offset().whole_seconds()) * NANOS_PER_SECOND;
let (offset_value, iana_value) = match iana {
// An IANA annotation wins over the numeric offset; the offset was
// still used above to compute the absolute time. The identifier
// is validated lazily, on first resolution against the host's
// timezone database.
Some(iana) => (Value::NULL, Value::object(vm.alloc_string(iana))),
None => (
Value::try_int(offset_ns).expect("offset fits in BAML int"),
Value::NULL,
),
};
let zoned = copy::time::ZonedDateTime {
_nanoseconds: Arc::new(num_bigint::BigInt::from(datetime.unix_timestamp_nanos())),
_offset_ns: offset_value,
_iana: iana_value,
};
Ok(zoned.to_value(vm))
}
}
impl BamlNamespaceTime for PackageBamlImpl {
fn _format_zoned(
epoch_ns: Arc<num_bigint::BigInt>,
offset_ns: i64,
iana: Option<&bex_str::BexStr>,
) -> Result<bex_str::BexStr, VmRustFnError> {View on GitHub (pinned to bd85ce9dee)
Solutions
- Validate/clean offset strings before parsing (offsets within ±23:59).
- Report to maintainers if a normal offset string triggers it.
- Upgrade the VM build where offset validation covers all parse paths.
Example fix
// before
let z = ZonedDateTime.parse("2024-01-01T00:00:00+99999999:00");
// after
let z = ZonedDateTime.parse("2024-01-01T00:00:00+05:30"); Defensive patterns
Strategy: validation
Validate before calling
// Check the offset portion of a timestamp string is within ±24h before parsing
fn offset_in_range(ts: &str) -> bool {
ts.rsplit_once(['+', '-']).and_then(|(_, o)| o.split(':').next())
.and_then(|h| h.parse::<i64>().ok())
.map(|h| h.abs() <= 24).unwrap_or(true)
} Try / catch
// Wrap parse in panic boundary when handling untrusted input std::panic::catch_unwind(|| ZonedDateTime_parse(ts)).unwrap_or_else(|_| Err(ParseError::BadOffset))
Prevention
- Sanitize timestamp strings from untrusted sources before parsing.
- Reject offsets beyond ±23:59 at the input boundary.
- Keep the VM updated so offset validation covers all parse paths.
When it happens
Trigger: Parsing a timezone string with an out-of-range custom offset, or internal state corruption causing an unvalidated offset to reach try_int.
Common situations: Malformed or hostile timestamp strings with absurd offset components (e.g. '+99999999:00') in date/time data being ingested.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- offset fits in BAML int
- class offset fits u32
- enum offset fits u32
- interface offset fits u32
- type-alias offset fits u32
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/34198d5676f07c68.
Report an issue: GitHub.