{"record":{"id":"41f937a62a8fade3","repo":"nautechsystems/nautilus_trader","slug":"invalid-booktype-enum-string-value-was-value","errorCode":null,"errorMessage":"invalid `BookType` enum string value, was '{value}'","messagePattern":"invalid `BookType` enum string value, was '(.+?)'","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/model/src/ffi/enums.rs","lineNumber":458,"sourceCode":"pub extern \"C\" fn book_type_to_cstr(value: BookType) -> *const c_char {\n    str_to_cstr(value.as_ref())\n}\n\n/// Returns an enum from a C string.\n///\n/// # Safety\n///\n/// Assumes `ptr` is a valid C string pointer.\n///\n/// # Panics\n///\n/// Panics if the C string does not correspond to a valid `BookType` variant.\n#[unsafe(no_mangle)]\npub unsafe extern \"C\" fn book_type_from_cstr(ptr: *const c_char) -> BookType {\n    abort_on_panic(|| {\n        let value = unsafe { cstr_as_str(ptr) };\n        BookType::from_str(value)\n            .unwrap_or_else(|_| panic!(\"invalid `BookType` enum string value, was '{value}'\"))\n    })\n}\n\n#[unsafe(no_mangle)]\npub extern \"C\" fn contingency_type_to_cstr(value: ContingencyTypeOptional) -> *const c_char {\n    str_to_cstr(value.as_ref())\n}\n\n/// Returns an enum from a C string.\n///\n/// # Safety\n///\n/// Assumes `ptr` is a valid C string pointer.\n///\n/// # Panics\n///\n/// Panics if the C string does not correspond to a valid `ContingencyTypeOptional` variant.\n#[unsafe(no_mangle)]","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/ffi/enums.rs#L440-L476","documentation":"`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`.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nbt = \"L2_BOOK\"\nbook_type_from_cstr(bt.encode())\n// after\nbt = \"L2_MBP\"  # canonical BookType spelling; prefer book_type_to_cstr(BookType.L2_MBP)\nbook_type_from_cstr(bt.encode())","handlingStrategy":"validation","validationCode":"VALID_BOOK_TYPES = {\"L1_MBP\", \"L2_MBP\", \"L3_MBO\"}  # verify against BookType definition\nassert bt_str in VALID_BOOK_TYPES, f\"bad BookType: {bt_str!r}\"\nbook_type_from_cstr(bt_str.encode())","typeGuard":"def is_valid_book_type(s: str) -> bool:\n    return s in VALID_BOOK_TYPES  # canonical strings from BookType::as_ref","tryCatchPattern":null,"preventionTips":["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."],"tags":["ffi","rust","panic","enum-parsing","process-abort"],"backgroundTag":"invalid-enum-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}