BoundaryML/baml · error
unknown run error class
Error message
unknown run error class: {other} What it means
run_error_class_from_proto (string-to-enum mapping) rejects any class string it does not recognize with InvalidData, listing the offending value. Known classes are runtime, host, panic, cancelled, internal; anything else (e.g. a new producer-side class or typo) fails the conversion.
Solutions
- Update the match arms in record.rs to handle the new class string
- Align producer to only emit the known class strings (lowercase, exact spelling)
- Normalize/whitelist class strings at the producer boundary before serialization
- Bump/sync the shared schema so both sides agree on the enum
Example fix
// before
match s.as_str() {
"runtime" => ..., "internal" => ..., other => return Err(...)
}
// after
match s.as_str() {
"runtime" => ..., "internal" => ..., "oom" => RunErrorClass::Oom, other => return Err(...)
} Defensive patterns
Strategy: validation
Validate before calling
const KNOWN: &[&str] = &["runtime","host","panic","cancelled","internal"];
fn is_known_class(s: &str) -> bool { KNOWN.contains(&s) } Try / catch
match convert_run_error(msg) {
Ok(rec) => rec,
Err(e) if e.to_string().starts_with("unknown run error class") => { log::warn!("{e}"); treat_as_internal(); },
Err(e) => return Err(e),
} Prevention
- Keep the class string enum in one shared schema module
- Map unknown producer classes to a fallback (internal) before emitting
- Add cross-version compatibility tests for the class mapping
When it happens
Trigger: TryFrom of a run-error record whose `class` string is not one of the five known variants — new enum values added upstream without updating this match, typos, or case mismatches ("Runtime" vs "runtime").
Common situations: Producer and consumer built from different schema versions where a new error class was added; hand-edited event payloads; localization/formatting of class strings before sending.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- BamlSerde cannot be derived for enums, use…
- cannot convert value
- cannot convert value
- capture loss omitted kind
- capture loss omitted reason
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/d341c2384312221d.
Report an issue: GitHub.
Appendix: source
Thrown at baml_language/crates/bex_events/src/value/record.rs:599
RunStatus::Cancelling => crate::value::pb::RunStatus::Cancelling,
RunStatus::Succeeded => crate::value::pb::RunStatus::Succeeded,
RunStatus::Failed => crate::value::pb::RunStatus::Failed,
RunStatus::Cancelled => crate::value::pb::RunStatus::Cancelled,
RunStatus::Panicked => crate::value::pb::RunStatus::Panicked,
}
}
fn run_error_from_proto(value: crate::value::pb::RunErrorV1) -> io::Result<RunError> {
Ok(RunError {
class: match value.class.as_str() {
"validation" => RunErrorClass::Validation,
"runtime" => RunErrorClass::Runtime,
"host" => RunErrorClass::Host,
"panic" => RunErrorClass::Panic,
"cancelled" => RunErrorClass::Cancelled,
"internal" => RunErrorClass::Internal,
other => {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("unknown run error class: {other}"),
));
}
},
message: value.message,
details: value.details,
value_ref: value.value_ref.map(ValueRef::try_from).transpose()?,
})
}
fn run_error_to_proto(value: &RunError) -> crate::value::pb::RunErrorV1 {
crate::value::pb::RunErrorV1 {
class: match value.class {
RunErrorClass::Validation => "validation",
RunErrorClass::Runtime => "runtime",
RunErrorClass::Host => "host",
RunErrorClass::Panic => "panic",View on GitHub (pinned to bd85ce9dee)