nautechsystems/nautilus_trader · critical
invalid `BookType` enum string value, was '{value}'
Error message
invalid `BookType` enum string value, was '{value}' What it means
`book_type_from_cstr` parses a C string into the Rust `BookType` enum (order book depth types) and panics if the string matches no variant. The library deliberately panics on unknown enum strings, and at the FFI boundary `abort_on_panic` turns that panic into a process abort rather than undefined behavior across the C ABI. Input must exactly equal a canonical `BookType` serialization from `book_type_to_cstr`.
Source
Thrown at crates/model/src/ffi/enums.rs:458
pub extern "C" fn book_type_to_cstr(value: BookType) -> *const c_char {
str_to_cstr(value.as_ref())
}
/// Returns an enum from a C string.
///
/// # Safety
///
/// Assumes `ptr` is a valid C string pointer.
///
/// # Panics
///
/// Panics if the C string does not correspond to a valid `BookType` variant.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn book_type_from_cstr(ptr: *const c_char) -> BookType {
abort_on_panic(|| {
let value = unsafe { cstr_as_str(ptr) };
BookType::from_str(value)
.unwrap_or_else(|_| panic!("invalid `BookType` enum string value, was '{value}'"))
})
}
#[unsafe(no_mangle)]
pub extern "C" fn contingency_type_to_cstr(value: ContingencyTypeOptional) -> *const c_char {
str_to_cstr(value.as_ref())
}
/// Returns an enum from a C string.
///
/// # Safety
///
/// Assumes `ptr` is a valid C string pointer.
///
/// # Panics
///
/// Panics if the C string does not correspond to a valid `ContingencyTypeOptional` variant.
#[unsafe(no_mangle)]View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the exact string and diff against canonical `BookType` variant spellings (see the enum's FromStr impl).
- Derive the string from the enum via `book_type_to_cstr` rather than hard-coding.
- Normalize case and strip whitespace before the call.
- Add an explicit mapping from config/feed vocabulary to `BookType` strings at the boundary.
- Validate before the call — invalid input aborts the whole process, not just the request.
Example fix
// before bt = "L2_BOOK" book_type_from_cstr(bt.encode()) // after bt = "L2_MBP" # canonical BookType spelling; prefer book_type_to_cstr(BookType.L2_MBP) book_type_from_cstr(bt.encode())
Defensive patterns
Strategy: validation
Validate before calling
VALID_BOOK_TYPES = {"L1_MBP", "L2_MBP", "L3_MBO"} # verify against BookType definition
assert bt_str in VALID_BOOK_TYPES, f"bad BookType: {bt_str!r}"
book_type_from_cstr(bt_str.encode()) Type guard
def is_valid_book_type(s: str) -> bool:
return s in VALID_BOOK_TYPES # canonical strings from BookType::as_ref Prevention
- Use the library's BookType enum serialization rather than vendor depth-level names.
- Normalize case before the FFI call.
- Validate config values against the canonical set at startup.
- Test hard-coded strings via round-trip with book_type_to_cstr in CI.
- Check for renamed variants when upgrading.
When it happens
Trigger: Calling `book_type_from_cstr(ptr)` with strings like 'l2'/'depth2' in the wrong form, an empty string, or a value from another vendor's book-type naming scheme.
Common situations: Configuring order book depth in a data-engine config; adapters translating venue depth levels into `BookType`; case/typo mistakes; enum spelling changes across NautilusTrader versions.
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
- invalid `AggressorSide` enum string value, was '{value}'
- invalid `AssetClass` enum string value, was '{value}'
- invalid `InstrumentClass` enum string value, was '{value}'
- invalid `BarAggregation` enum string value, was '{value}'
- invalid `BookAction` enum string value, was '{value}'
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/41f937a62a8fade3.
Report an issue: GitHub.