{"record":{"id":"bf5cf9125b1bec16","repo":"nautechsystems/nautilus_trader","slug":"failed-to-decode-cap-n-proto","errorCode":null,"errorMessage":"failed to decode Cap'n Proto {}: {}","messagePattern":"failed to decode Cap'n Proto (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/common/src/msgbus/external/codec/capnp.rs","lineNumber":43,"sourceCode":"    capnp::{FromCapnp, ToCapnp},\n    market_capnp,\n};\n\nuse super::PayloadCodecError;\nuse crate::msgbus::BusPayloadType;\n\nmacro_rules! deserialize_payload_as {\n    ($payload:expr, $type_name:expr, $ty:ty, $root:ty) => {{\n        let reader = ::capnp::serialize::read_message(\n            &mut &$payload[..],\n            ::capnp::message::ReaderOptions::new(),\n        )\n        .context(\"failed to read Cap'n Proto message\")?;\n        let root = reader\n            .get_root::<$root>()\n            .with_context(|| format!(\"Cap'n Proto payload has no {} root\", $type_name))?;\n        <$ty>::from_capnp(root)\n            .map_err(|e| anyhow::anyhow!(\"failed to decode Cap'n Proto {}: {}\", $type_name, e))\n    }};\n}\n\nmacro_rules! define_deserializer {\n    ($fn_name:ident, $ty:ty, $type_name:literal, $root:ty) => {\n        pub(crate) fn $fn_name(payload: &[u8]) -> anyhow::Result<$ty> {\n            deserialize_payload_as!(payload, $type_name, $ty, $root)\n        }\n    };\n}\n\ndefine_deserializer!(\n    deserialize_order_book_deltas,\n    OrderBookDeltas,\n    \"OrderBookDeltas\",\n    market_capnp::order_book_deltas::Reader\n);\ndefine_deserializer!(","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/msgbus/external/codec/capnp.rs#L25-L61","documentation":"Raised by the Cap'n Proto deserializer macro in the msgbus external codec when a message payload cannot be decoded into the target type. Reading the segments or the root may fail, but this specific error comes from the type's from_capnp conversion failing — the bytes were readable but did not represent a valid message of the expected type.","triggerScenarios":"Feeding a payload produced by a different message type or schema version into the generated deserialize_<type> function; truncated or corrupted payloads; decoding a payload from a peer running an incompatible schema.","commonSituations":"Schema drift between publisher and subscriber after a message definition change; routing the wrong byte stream to a codec; interop between different nautilus versions with changed Cap'n Proto definitions.","solutions":["Verify the payload was produced by the matching Cap'n Proto message type and deserializer function.","Ensure publisher and subscriber use the same schema/version of the message definitions.","Check payload integrity — confirm the bytes are complete and not truncated or corrupted in transit.","Regenerate codec code from the current .capnp schema files if definitions changed."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match deserialize_order_book_delta(payload) {\n    Ok(msg) => handle(msg),\n    Err(e) if e.to_string().contains(\"failed to decode Cap'n Proto\") => {\n        log::warn!(\"dropping undecodable capnp payload: {e:#}\");\n        // inspect schema versions / route to dead-letter queue\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Keep Cap'n Proto schemas in lockstep between publisher and consumer.","Tag or envelope messages with a type identifier so the correct deserializer is chosen.","Pin message schema versions in interop tests between nautilus versions.","Check payload integrity (length, framing) before handing bytes to the codec."],"tags":["rust","capnp","serialization","messaging"],"backgroundTag":"protobuf-unmarshal-failed","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"}