{"record":{"id":"66dcd138d5a82d37","repo":"BoundaryML/baml","slug":"baml-panics-indexoutofbounds","errorCode":"baml.panics.IndexOutOfBounds","errorMessage":"index out of bounds: {index} of {length}","messagePattern":"index out of bounds: (.+?) of (.+?)","errorType":"error_code","errorClass":"VmPanic","httpStatus":null,"severity":"error","filePath":"baml_language/crates/bex_vm_types/src/errors.rs","lineNumber":36,"sourceCode":"///\n/// These are user-visible runtime errors (division by zero, index out of\n/// bounds, etc.) that can be caught by `catch` handlers. The handler's\n/// `ThrowIfPanic` instruction filters which panics are caught vs rethrown.\n#[derive(Debug, Error, PartialEq, Clone)]\npub enum VmPanic {\n    #[error(\"division by zero: {left:?} / {right:?}\")]\n    DivisionByZero { left: Value, right: Value },\n\n    /// An `int` (i63) arithmetic operation overflowed the representable\n    /// range `[INT_MIN, INT_MAX]`. Carries a human-readable description of\n    /// the operation (e.g. `\"4611686018427387903 + 1\"`); built only on the\n    /// cold overflow path, so the `String` alloc never touches hot code.\n    #[error(\"integer overflow: {message}\")]\n    IntegerOverflow { message: String },\n\n    // Raised by array and byte-array subscripting, so the message stays generic\n    // (\"index\", not \"array index\").\n    #[error(\"index out of bounds: {index} of {length}\")]\n    IndexOutOfBounds { index: i64, length: usize },\n\n    #[error(\"invalid field access: field {field_index} of {field_count}\")]\n    InvalidFieldAccess {\n        field_index: usize,\n        field_count: usize,\n    },\n\n    #[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\")]","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bex_vm_types/src/errors.rs#L18-L54","documentation":"Raised by array and byte-array subscripting when an index is outside the valid range of the container. The message stays generic (\"index\", not \"array index\") because both arrays and byte arrays use it. It reports the offending index and the container's length.","triggerScenarios":"Evaluating `arr[i]` or `bytes[i]` where `i` is negative or >= the collection length, e.g. `bytes[bytes.length]` or indexing with a computed offset that went out of range.","commonSituations":"Off-by-one in loops (`i <= len` instead of `i < len`), empty arrays indexed at 0, parsing byte payloads with assumed fixed offsets, index math from user input or unvalidated parse results.","solutions":["Check `0 <= index && index < arr.length` before subscripting.","Catch `baml.panics.IndexOutOfBounds` around the access if the lookup is optional.","Compute length-derived indices from the actual `.length` rather than hardcoded constants."],"exampleFix":"// before\nlet last = items[items.length];\n// after\nlet last = items[items.length - 1];","handlingStrategy":"validation","validationCode":"// BAML: check before subscripting\nif (i < 0 || i >= items.length) { return err(\"bad index\"); }\nlet v = items[i];","typeGuard":null,"tryCatchPattern":"// BAML\ntry {\n  let v = bytes[i];\n} catch (e: baml.panics.IndexOutOfBounds) {\n  return default_value;\n}","preventionTips":["Use `i < len` not `i <= len` in loops","Guard index 0 accesses on possibly-empty collections","Derive offsets from `.length`, never hardcode them"],"tags":["vm","array","subscript","panic","baml"],"backgroundTag":"index-out-of-bounds","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"}