{"record":{"id":"2a958fb1a5126c5c","repo":"nautechsystems/nautilus_trader","slug":"invalid-rtds-crypto-twap-payload-e","errorCode":null,"errorMessage":"invalid RTDS crypto TWAP payload: {e}","messagePattern":"invalid RTDS crypto TWAP payload: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/rtds.rs","lineNumber":1303,"sourceCode":"                ts_init,\n            ));\n\n            self.emit_custom_payload(&custom_payload, data_types.clone());\n        }\n    }\n\n    fn handle_crypto_twap_update(\n        &self,\n        envelope: &RtdsEnvelope,\n        window: RtdsCryptoTwapWindow,\n    ) -> anyhow::Result<()> {\n        let topic = window.topic();\n        if !self.has_topic_subscription(topic.as_str()) {\n            return Ok(());\n        }\n\n        let payload: CryptoTwapPayloadRaw = serde_json::from_str(envelope.payload.get())\n            .map_err(|e| anyhow::anyhow!(\"invalid RTDS crypto TWAP payload: {e}\"))?;\n        if payload.window_s != window.seconds() {\n            anyhow::bail!(\n                \"RTDS TWAP topic {:?} requires window_s={}, received {}\",\n                topic.as_str(),\n                window.seconds(),\n                payload.window_s,\n            );\n        }\n        let symbol_lower = payload.symbol.to_ascii_lowercase();\n        let value =\n            decimal_from_signed_e18(\"full_accuracy_value\", payload.full_accuracy_value.as_str())?;\n        let ts_event = unix_nanos_from_millis(\"payload.timestamp\", payload.timestamp)?;\n        unix_nanos_from_millis(\"envelope.timestamp\", envelope.timestamp)?;\n        let Some(data_types) =\n            self.admit_twap_observation(topic, &symbol_lower, payload.timestamp, value)?\n        else {\n            return Ok(());\n        };","sourceCodeStart":1285,"sourceCodeEnd":1321,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/rtds.rs#L1285-L1321","documentation":"When a crypto TWAP message arrives on a subscribed RTDS topic, the envelope payload string is deserialized into CryptoTwapPayloadRaw. Failure raises 'invalid RTDS crypto TWAP payload: {e}'. This guards against malformed or schema-drifted payloads before window validation.","triggerScenarios":"Receiving a message on a subscribed crypto TWAP topic whose JSON does not match CryptoTwapPayloadRaw (missing fields like window_s, wrong types, HTML/JSON error bodies, empty payload).","commonSituations":"Polymarket RTDS schema changes to the TWAP payload, gateway emitting error messages on subscribed topics, or proxy/firewall injecting non-JSON content into the stream.","solutions":["Log the raw envelope payload alongside the serde error to see what the gateway actually sent","Verify the subscription topic/window matches the crypto TWAP schema you expect","Update the adapter if Polymarket changed the CryptoTwapPayloadRaw field names or types","Add a tolerance/skip path: ignore unparseable messages instead of failing the message loop if they are non-essential"],"exampleFix":"// before\nlet payload: CryptoTwapPayloadRaw = serde_json::from_str(envelope.payload.get())?;\n// after\nlet payload: CryptoTwapPayloadRaw = serde_json::from_str(envelope.payload.get())\n    .inspect_err(|e| warn!(\"TWAP payload: {} err: {e}\", envelope.payload.get()))?;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Rust: log and skip malformed TWAP messages instead of failing the loop\nlet payload: CryptoTwapPayloadRaw = match serde_json::from_str(envelope.payload.get()) {\n    Ok(p) => p,\n    Err(e) => { warn!(\"skipping invalid TWAP payload: {e}\"); return Ok(()); }\n};","preventionTips":["Log the raw payload on every deserialization failure to catch schema drift early","Pin adapter versions to compatible RTDS message schemas and update on API changes","Ignore non-data frames (pings/errors) routed onto subscribed topics"],"tags":["deserialization","json","polymarket","rtds","realtime"],"backgroundTag":"json-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"}