{"record":{"id":"f122989123c73da4","repo":"nautechsystems/nautilus_trader","slug":"invalid-instrumentclosetype-enum-string-value-w","errorCode":null,"errorMessage":"invalid `InstrumentCloseType` enum string value, was '{value}'","messagePattern":"invalid `InstrumentCloseType` enum string value, was '(.+?)'","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/model/src/ffi/enums.rs","lineNumber":525,"sourceCode":"}\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 `InstrumentCloseType` variant.\n#[unsafe(no_mangle)]\npub unsafe extern \"C\" fn instrument_close_type_from_cstr(\n    ptr: *const c_char,\n) -> InstrumentCloseType {\n    abort_on_panic(|| {\n        let value = unsafe { cstr_as_str(ptr) };\n        InstrumentCloseType::from_str(value).unwrap_or_else(|_| {\n            panic!(\"invalid `InstrumentCloseType` enum string value, was '{value}'\")\n        })\n    })\n}\n\n#[unsafe(no_mangle)]\npub extern \"C\" fn instrument_close_type_to_cstr(value: InstrumentCloseType) -> *const c_char {\n    str_to_cstr(value.as_ref())\n}\n\n#[unsafe(no_mangle)]\npub extern \"C\" fn liquidity_side_to_cstr(value: LiquiditySide) -> *const c_char {\n    str_to_cstr(value.as_ref())\n}\n\n/// Returns an enum from a C string.\n///\n/// # Safety\n///","sourceCodeStart":507,"sourceCodeEnd":543,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/ffi/enums.rs#L507-L543","documentation":"`instrument_close_type_from_cstr` converts a C string into the Rust `InstrumentCloseType` enum (close semantics such as expiration) and panics when the string matches no variant. The panic is wrapped in `abort_on_panic` because the function is an FFI export; an invalid string therefore aborts the host process rather than unwinding across the C ABI. Only exact canonical serializations from `instrument_close_type_to_cstr` are valid.","triggerScenarios":"Calling `instrument_close_type_from_cstr(ptr)` with a non-canonical close-type string (e.g. 'expiry', empty string, wrong case), or a value from a data vendor's instrument-lifecycle vocabulary.","commonSituations":"Loading futures/options instruments with close semantics from external catalogs; adapters mapping vendor instrument specs; typos; spelling changes across library versions.","solutions":["Dump the exact string and compare with the canonical `InstrumentCloseType` variant spellings in the model enums.","Produce strings via `instrument_close_type_to_cstr` from enum values instead of literals.","Normalize case/whitespace; matching is exact.","Add an explicit vendor-term -> InstrumentCloseType mapping at the data-ingestion boundary.","Pre-validate against the accepted variant set before the FFI call to avoid a hard abort."],"exampleFix":"// before\nclose_type = \"expiry\"\ninstrument_close_type_from_cstr(close_type.encode())\n// after\nclose_type = \"EXPIRATION\"  # verify canonical spelling via instrument_close_type_to_cstr\ninstrument_close_type_from_cstr(close_type.encode())","handlingStrategy":"validation","validationCode":"VALID_CLOSE_TYPES = {\"EXPIRATION\", \"DELISTING\"}  # verify against InstrumentCloseType definition\nassert close_type_str in VALID_CLOSE_TYPES, f\"bad InstrumentCloseType: {close_type_str!r}\"\ninstrument_close_type_from_cstr(close_type_str.encode())","typeGuard":"def is_valid_instrument_close_type(s: str) -> bool:\n    return s in VALID_CLOSE_TYPES  # canonical strings from InstrumentCloseType::as_ref","tryCatchPattern":null,"preventionTips":["Map vendor instrument-lifecycle terms to InstrumentCloseType explicitly at ingestion.","Normalize case/whitespace before the FFI call.","Validate against the accepted variant set to avoid a process abort.","Use instrument_close_type_to_cstr to generate strings from enum values.","Diff hard-coded strings against the enum after upgrades."],"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"}