nautechsystems/nautilus_trader · error
Invalid `OptionKind`, was '{invalid}'
Error message
Invalid `OptionKind`, was '{invalid}' What it means
parse_option_kind maps a Databento option-kind character (the call/put discriminant) to an OptionKind; any character outside the valid discriminant set fails here before the option contract is decoded.
Source
Thrown at crates/adapters/databento/src/decode/primitives.rs:85
'R' => Ok(BookAction::Clear),
// 'F' (Fill) and 'N' (None) are deliberately NOT book actions: fills
// are attribution records whose book impact arrives as the explicit
// Cancel/Modify of the same match event (`decode_mbo_msg` filters
// them out before calling this).
invalid => anyhow::bail!("Invalid `BookAction`, was '{invalid}'"),
}
}
/// Parses a Databento option kind character into an `OptionKind` enum.
///
/// # Errors
///
/// Returns an error if `c` is not a valid `OptionKind` character.
pub fn parse_option_kind(c: c_char) -> anyhow::Result<OptionKind> {
match c as u8 as char {
'C' => Ok(OptionKind::Call),
'P' => Ok(OptionKind::Put),
invalid => anyhow::bail!("Invalid `OptionKind`, was '{invalid}'"),
}
}
pub(super) fn parse_currency_or_usd_default(
value: Result<&str, impl std::error::Error>,
) -> Currency {
match value {
Ok(value) if !value.is_empty() => Currency::try_from_str(value).unwrap_or_else(|| {
log::warn!("Unknown currency code '{value}', defaulting to USD");
Currency::USD()
}),
Ok(_) => Currency::USD(),
Err(e) => {
log::warn!("Error parsing currency: {e}");
Currency::USD()
}
}
}View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the instrument definition's option_kind field is 'C' or 'P'
- Check that the record really is an option contract (asset class / instrument_class)
- Fix or regenerate corrupted definition data from Databento
- Normalize case upstream if your data uses lowercase c/p
Example fix
// before option_kind: b'c' // after option_kind: b'C' // 'C' call or 'P' put only
Defensive patterns
Strategy: validation
Validate before calling
fn is_valid_option_kind(c: u8) -> bool { matches!(c, b'C' | b'P') }
fn validate_definition(def: &dbn::InstrumentDefMsg) -> Result<(), String> {
if def.instrument_class == dbn::InstrumentClass::Option && !is_valid_option_kind(def.option_kind as u8) {
return Err(format!("bad option_kind: {}", def.option_kind));
}
Ok(())
} Type guard
fn is_call_or_put(c: u8) -> Option<OptionKindSide> { match c { b'C' => Some(Call), b'P' => Some(Put), _ => None } } Try / catch
match decode_option_contract(def) {
Ok(c) => c,
Err(e) if e.to_string().contains("Invalid `OptionKind`") => { /* skip non-option/malformed record */ }
Err(e) => return Err(e),
} Prevention
- Confirm instrument_class is Option before option-kind decoding
- Normalize kind chars to uppercase 'C'/'P' in your pipeline
- Validate definitions before decoding contracts
When it happens
Trigger: Decoding an option contract definition whose `option_kind` field is neither 'C' nor 'P' (e.g. empty, 'c'/'p' lowercase, or a placeholder char).
Common situations: Malformed instrument definition records; upstream schema changes; manually constructed test definitions with the wrong kind character; non-option records accidentally routed through option decoding.
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 `BookAction`, was '{invalid}'
- Invalid `StatusMsg` reason, was '{invalid}'
- Invalid `StatusMsg` trading_event, was '{value}'
- option_summary_family_subs mutex poisoned
- Invalid NodeState value
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/c05ced7094d9401b.
Report an issue: GitHub.