{"record":{"id":"47d25d6ef9d502b6","repo":"nautechsystems/nautilus_trader","slug":"invalid-bookaction-was-invalid","errorCode":null,"errorMessage":"Invalid `BookAction`, was '{invalid}'","messagePattern":"Invalid `BookAction`, was '(.+?)'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/databento/src/decode/primitives.rs","lineNumber":72,"sourceCode":"    }\n}\n\n/// Parses a Databento book action character into a `BookAction` enum.\n///\n/// # Errors\n///\n/// Returns an error if `c` is not a valid `BookAction` character.\npub fn parse_book_action(c: c_char) -> anyhow::Result<BookAction> {\n    match c as u8 as char {\n        'A' => Ok(BookAction::Add),\n        'C' => Ok(BookAction::Delete),\n        'M' => Ok(BookAction::Update),\n        'R' => Ok(BookAction::Clear),\n        // 'F' (Fill) and 'N' (None) are deliberately NOT book actions: fills\n        // are attribution records whose book impact arrives as the explicit\n        // Cancel/Modify of the same match event (`decode_mbo_msg` filters\n        // them out before calling this).\n        invalid => anyhow::bail!(\"Invalid `BookAction`, was '{invalid}'\"),\n    }\n}\n\n/// Parses a Databento option kind character into an `OptionKind` enum.\n///\n/// # Errors\n///\n/// Returns an error if `c` is not a valid `OptionKind` character.\npub fn parse_option_kind(c: c_char) -> anyhow::Result<OptionKind> {\n    match c as u8 as char {\n        'C' => Ok(OptionKind::Call),\n        'P' => Ok(OptionKind::Put),\n        invalid => anyhow::bail!(\"Invalid `OptionKind`, was '{invalid}'\"),\n    }\n}\n\npub(super) fn parse_currency_or_usd_default(\n    value: Result<&str, impl std::error::Error>,","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/databento/src/decode/primitives.rs#L54-L90","documentation":"`parse_book_action` converts the Databento MBO action character ('A' add, 'C' cancel, 'M' modify, 'R' clear) into a `BookAction` enum. Fill ('F') and None ('N') are deliberately excluded because their book impact arrives as explicit Cancel/Modify events; any other character is invalid and bails.","triggerScenarios":"Decoding an `MboMsg` whose `action` field is a character outside {'A','C','M','R'} (and the deliberately-unsupported 'F'/'N' which decode_mbo_msg should filter out first).","commonSituations":"Corrupt or truncated records; new Databento action codes added upstream; feeding hand-crafted MBO records in tests or replay with a wrong action char.","solutions":["Verify the record's action field against the Databento MBO spec","Ensure 'F'/'N' records are filtered before parse (decode_mbo_msg does this) — upgrade if your version doesn't","Upgrade the adapter/dbn crates if Databento introduced new action codes","Sanitize or drop corrupt records at the stream source"],"exampleFix":"// before\nMboMsg { action: b'X', ... } // invalid action char\n// after\nMboMsg { action: b'A', ... } // A/C/M/R only","handlingStrategy":"validation","validationCode":"fn is_valid_book_action(action: u8) -> bool { matches!(action, b'A' | b'C' | b'M' | b'R') }\n// filter 'F' and 'N' before decode, as decode_mbo_msg does","typeGuard":"fn is_book_action(action: u8) -> Option<u8> { matches!(action, b'A'|b'C'|b'M'|b'R').then_some(action) }","tryCatchPattern":"match decode_record(record) {\n    Ok(d) => d,\n    Err(e) if e.to_string().contains(\"Invalid `BookAction`\") => { /* drop corrupt record */ }\n    Err(e) => return Err(e),\n}","preventionTips":["Validate MBO action chars against {'A','C','M','R'} at ingest","Filter 'F'/'N' action records before book decoding","Sanitize replay/test data to use only documented action codes","Keep dbn/adapter versions current for new action codes"],"tags":["rust","databento","order-book","enum"],"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"}