BoundaryML/baml · info · EngineError

baml.sys.exit({code})

Error message

baml.sys.exit({code})

What it means

Not a failure: a structured signal raised when BAML code calls `baml.sys.exit(code)`, requesting clean process termination. The error variant carries the full i64 exit code; the embedding caller is expected to honor it as the process exit status, clamping to the shell's range (typically 0..=255 on Unix).

Source

Thrown at baml_language/crates/bex_engine/src/lib.rs:839

    #[error("{}", format_vm_internal_error(source, trace))]
    TracedVmInternalError {
        source: bex_vm::errors::VmInternalError,
        trace: Vec<bex_vm::StackFrame>,
    },

    /// Either a BAML panic or a BAML error value.
    #[error("{}", format_unhandled_throw(value, trace))]
    UnhandledThrow {
        value: Box<BexExternalValue>,
        trace: Vec<bex_vm::StackFrame>,
    },

    /// Clean process-termination request from `baml.sys.exit(code)`.
    /// The caller is expected to honor this as the process exit code.
    /// BAML `int` is `i64`, so the signal carries the full value; the
    /// caller clamps into its shell's range (typically 0..=255 on Unix).
    #[error("baml.sys.exit({code})")]
    Exit { code: i64 },

    #[error("Cannot convert object of type {type_name}")]
    CannotConvert { type_name: String },

    #[error("Type mismatch: {message}")]
    TypeMismatch { message: String },

    #[error("Schema inconsistency: {message}")]
    SchemaInconsistency { message: String },

    #[cfg(feature = "heap_debug")]
    #[error("Snapshot not possible for type: {type_name}")]
    CannotSnapshot { type_name: String },

    #[error("A function call with ID {call_id} is already in progress")]
    DuplicateCallId { call_id: CallId },

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Catch/handle this variant in the host and exit the process with the given code (clamped to 0..=255)
  2. If exit is unexpected, audit the BAML code for baml.sys.exit calls
  3. In server embeddings, translate it into a request-scoped abort rather than killing the process

Example fix

// host code (rust, conceptual)
// before: treats it as generic failure
Err(e) => panic!("{}", e),
// after
Err(EngineError::Exit { code }) => std::process::exit(code.clamp(0, 255) as i32),
Defensive patterns

Strategy: try-catch

Try / catch

match result {
    Err(EngineError::Exit { code }) => std::process::exit(code.clamp(0, 255) as i32),
    Ok(v) => use(v),
    Err(e) => handle(e),
}

Prevention

When it happens

Trigger: A BAML function calls `baml.sys.exit(code)` and the engine surfaces it as this variant instead of terminating the host process directly.

Common situations: CLI-style BAML scripts that want to set their Unix exit status; tests that trigger early-exit paths; embedding the engine in a server where exit must be intercepted.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/b9b2961a3f660bb3. Report an issue: GitHub.