{"record":{"id":"f5a30885567ee072","repo":"BoundaryML/baml","slug":"baml-panics-userpanic","errorCode":"baml.panics.UserPanic","errorMessage":"baml.sys.panic: {message}","messagePattern":"baml\\.sys\\.panic: (.+?)","errorType":"error_code","errorClass":"VmPanic","httpStatus":null,"severity":"error","filePath":"baml_language/crates/bex_vm_types/src/errors.rs","lineNumber":63,"sourceCode":"    #[error(\"key not found in map\")]\n    MapKeyNotFound,\n\n    #[error(\"stack overflow\")]\n    StackOverflow,\n\n    #[error(\"assertion failed\")]\n    AssertionFailed,\n\n    #[error(\"unreachable code executed\")]\n    Unreachable,\n\n    #[error(\"operation cancelled\")]\n    Cancelled,\n\n    /// A user-caused panic from `baml.sys.panic`, and the stdlib's panic of\n    /// record for a user-violated native invariant (e.g. a reflection kind\n    /// view's `_ty` field overwritten with a type of a different kind).\n    #[error(\"baml.sys.panic: {message}\")]\n    UserPanic { message: String },\n\n    /// A clean process-termination request from `baml.sys.exit(code)`.\n    ///\n    /// Catchable in user code as `baml.panics.Exit` — patterned after\n    /// Python's `SystemExit`: code can intercept it for cleanup or\n    /// testing, and if nothing catches it the engine surfaces the code\n    /// as `EngineError::Exit` and the host terminates with it.\n    ///\n    /// BAML `int` is `i64`, so the signal carries the full value the\n    /// user wrote; the host narrows to `i32` for `std::process::exit`.\n    #[error(\"baml.sys.exit({code})\")]\n    Exit { code: i64 },\n\n    /// The graceful-ish way to handle potential OOM errors, instead of hard-crashing.\n    #[error(\"memory allocation failed: {message}\")]\n    AllocFailure { message: String },\n","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bex_vm_types/src/errors.rs#L45-L81","documentation":"A user-caused panic raised by `baml.sys.panic(message)` from BAML code, or by the stdlib panicking on a user-violated native invariant (e.g. a reflection kind view's `_ty` field overwritten with a type of a different kind). The message is the programmer-provided description.","triggerScenarios":"BAML code calls `baml.sys.panic(\"...\")` directly; or user code mutates a native record's invariant field such as writing a mismatched type into a reflection view's `_ty` field.","commonSituations":"Deliberate fail-fast on invalid input in BAML functions, misuse of the reflection/stdin native APIs, writing to internals that the stdlib assumes are well-formed.","solutions":["Read the message to identify the failing check and fix the calling BAML code.","Catch `baml.panics.UserPanic` in BAML to convert the panic into a controlled error path.","Do not overwrite native invariant fields (like `_ty` on reflection views); use the provided APIs."],"exampleFix":"// before\nview._ty = some_int_type; // wrong kind\n// after\nview._ty = some_record_type; // keep the kind consistent with the view","handlingStrategy":"try-catch","validationCode":"// BAML: validate before panicking\nif (value == null) { return err(\"value required\"); }","typeGuard":"// BAML: guard reflection views before mutation\nif (is_kind_view(v) && kind_of(ty) == expected_kind) { v._ty = ty; }","tryCatchPattern":"// BAML\ntry {\n  risky();\n} catch (e: baml.panics.UserPanic) {\n  return err(e.message);\n}","preventionTips":["Prefer returning errors over baml.sys.panic for expected failure paths","Never write mismatched types into native `_ty` fields","Keep panic messages actionable — they become the error text"],"tags":["vm","user-panic","stdlib","panic","baml"],"backgroundTag":"invalid-argument-value","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}