BoundaryML/baml · error
writing to a String cannot fail
Error message
writing to a String cannot fail
What it means
A panic from `write!(self.text, "{value}").expect("writing to a String cannot fail")` inside the `text()` builder method of the diagnostic message type. Formatting into a Rust `String` can only fail if the underlying formatter fails, which for `String` targets is essentially impossible; this expect converts an unrecoverable formatting error into a panic. In practice it panics only when the Display impl of the interpolated value panics or misbehaves, or if a gigantic formatted value exhausts memory during string growth.
Source
Thrown at baml_language/crates/baml_compiler_diagnostics/src/message.rs:66
.map(|offset| content_start + offset)
else {
break;
};
if content_start < close {
highlights.push(DiagnosticMessageHighlight {
start: u32::try_from(content_start).expect("diagnostic text exceeds 4 GiB"),
end: u32::try_from(close).expect("diagnostic text exceeds 4 GiB"),
kind: DiagnosticMessageKind::Code,
});
}
cursor = close + 1;
}
Self { text, highlights }
}
#[must_use]
pub fn text(mut self, value: impl fmt::Display) -> Self {
write!(self.text, "{value}").expect("writing to a String cannot fail");
self
}
#[must_use]
pub fn identifier(self, value: impl fmt::Display, kind: DiagnosticIdentifierKind) -> Self {
self.fragment(value, DiagnosticMessageKind::Identifier(kind))
}
#[must_use]
pub fn type_expr(self, value: impl fmt::Display) -> Self {
self.fragment(value, DiagnosticMessageKind::TypeExpression)
}
#[must_use]
pub fn code(self, value: impl fmt::Display) -> Self {
self.fragment(value, DiagnosticMessageKind::Code)
}
View on GitHub (pinned to bd85ce9dee)
Solutions
- Inspect the `Display` implementation of the value passed to `.text()`; fix any panic/unwrap inside it.
- Shrink or truncate the value before formatting (e.g. format a summary or snippet, not the whole object/file).
- Avoid deeply recursive or unbounded Debug/Display output that can balloon the message string; cap the payload size.
- If memory pressure is the cause, reduce concurrent compiler work or stream diagnostics instead of buffering one huge message.
Example fix
// before
msg.text(raw_file_contents)
// after
msg.text(truncate(&raw_file_contents, 2048))
fn truncate(s: &str, max: usize) -> &str { match s.char_indices().nth(max) { Some((i, _)) => &s[..i], None => s } } Defensive patterns
Strategy: type-guard
Validate before calling
fn safe_display(value: &impl fmt::Display) -> bool {
// Display cannot be pre-run without side effects; instead bound the formatted size:
true
}
// Guard: only pass bounded, trusted values into .text()
fn is_bounded(s: &str, max: usize) -> bool { s.len() <= max } Type guard
fn is_panics_free_display<T: fmt::Display>(_: &T) -> bool { true }
// Prefer guarding the value's size before formatting:
fn guard_size(s: &str) -> bool { s.len() <= 64 * 1024 } Try / catch
let msg = std::panic::catch_unwind(|| builder.text(value))
.unwrap_or_else(|_| builder.text("<unformattable value>")); Prevention
- Audit Display impls of values passed to diagnostics; remove unwrap/panic paths inside them.
- Truncate large payloads before formatting.
- Avoid formatting whole file contents or deeply nested Debug output.
- Wrap diagnostic construction in catch_unwind when handling untrusted input.
When it happens
Trigger: Calling `.text(value)` on the diagnostic builder where `value`'s `Display` implementation panics (e.g. it unwraps on invalid internal state) or where formatting a value larger than available memory forces an allocation failure in `String::push_str`.
Common situations: Passing a custom/newtype whose Display impl panics (unwrap on None, division by zero); passing a value that expands to terabytes (nested debug output); OOM conditions on memory-constrained machines while building large diagnostics.
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
- sys_op callee must resolve to a statically-known global func
- expected jump instruction at index {instruction_idx}
- exhaustive realized-leaf template classification
- ntypeargs fits u16
- interface `{iface_wire}` declares a non-runtime type: {e:?}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/d6e597db91774e50.
Report an issue: GitHub.