nautechsystems/nautilus_trader · critical
invalid `InstrumentCloseType` enum string value, was '{value
Error message
invalid `InstrumentCloseType` enum string value, was '{value}' What it means
`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.
Source
Thrown at crates/model/src/ffi/enums.rs:525
}
/// 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 `InstrumentCloseType` variant.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn instrument_close_type_from_cstr(
ptr: *const c_char,
) -> InstrumentCloseType {
abort_on_panic(|| {
let value = unsafe { cstr_as_str(ptr) };
InstrumentCloseType::from_str(value).unwrap_or_else(|_| {
panic!("invalid `InstrumentCloseType` enum string value, was '{value}'")
})
})
}
#[unsafe(no_mangle)]
pub extern "C" fn instrument_close_type_to_cstr(value: InstrumentCloseType) -> *const c_char {
str_to_cstr(value.as_ref())
}
#[unsafe(no_mangle)]
pub extern "C" fn liquidity_side_to_cstr(value: LiquiditySide) -> *const c_char {
str_to_cstr(value.as_ref())
}
/// Returns an enum from a C string.
///
/// # Safety
///View on GitHub (pinned to 18893faf8b)
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.
Example fix
// before close_type = "expiry" instrument_close_type_from_cstr(close_type.encode()) // after close_type = "EXPIRATION" # verify canonical spelling via instrument_close_type_to_cstr instrument_close_type_from_cstr(close_type.encode())
Defensive patterns
Strategy: validation
Validate before calling
VALID_CLOSE_TYPES = {"EXPIRATION", "DELISTING"} # verify against InstrumentCloseType definition
assert close_type_str in VALID_CLOSE_TYPES, f"bad InstrumentCloseType: {close_type_str!r}"
instrument_close_type_from_cstr(close_type_str.encode()) Type guard
def is_valid_instrument_close_type(s: str) -> bool:
return s in VALID_CLOSE_TYPES # canonical strings from InstrumentCloseType::as_ref Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Loading futures/options instruments with close semantics from external catalogs; adapters mapping vendor instrument specs; typos; spelling changes across library 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/f122989123c73da4.
Report an issue: GitHub.