{"record":{"id":"e7a12f19e93f3971","repo":"nautechsystems/nautilus_trader","slug":"failed-to-serialize-fill-info-e","errorCode":null,"errorMessage":"Failed to serialize fill info: {e}","messagePattern":"Failed to serialize fill info: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/infrastructure/src/sql/queries.rs","lineNumber":1030,"sourceCode":"        sqlx::query(\n            r#\"\n            INSERT INTO \"trader\" (id)\n            VALUES ($1)\n            ON CONFLICT (id) DO NOTHING\n        \"#,\n        )\n        .bind(event.trader_id.to_string())\n        .execute(&mut **transaction)\n        .await\n        .map(|_| ())\n        .map_err(|e| anyhow::anyhow!(\"Failed to insert into trader table: {e}\"))?;\n\n        let position_event_info = event\n            .info\n            .clone()\n            .map(serde_json::to_value)\n            .transpose()\n            .map_err(|e| anyhow::anyhow!(\"Failed to serialize fill info: {e}\"))?;\n\n        sqlx::query(\n            r#\"\n            INSERT INTO \"position_event\" (\n                id, kind, trader_id, strategy_id, instrument_id, client_order_id, venue_order_id,\n                account_id, trade_id, currency, order_type, order_side, last_px, last_qty,\n                liquidity_side, position_id, commission, reconciliation, info, causation_id,\n                ts_event, ts_init, created_at, updated_at\n            ) VALUES (\n                $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17,\n                $18, $19, $20, $21, $22, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP\n            )\n        \"#,\n        )\n        .bind(event.event_id.to_string())\n        .bind(\"OrderFilled\")\n        .bind(event.trader_id.to_string())\n        .bind(event.strategy_id.to_string())","sourceCodeStart":1012,"sourceCodeEnd":1048,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/infrastructure/src/sql/queries.rs#L1012-L1048","documentation":"insert_position_event serializes the optional OrderFilled.info field to a serde_json::Value before binding it into the position_event INSERT. If serde_json::to_value fails (e.g. a map key that is not a string, or a custom Serialize impl that errors), the error is wrapped with this message. This happens before any SQL runs, so nothing was written.","triggerScenarios":"An OrderFilled whose info field is Some(value) where serializing that value fails — classically a JSON object built with non-string keys (serde_json requires string map keys) or a Serialize implementation returning Err.","commonSituations":"A strategy attaching an info payload built from a HashMap with non-string keys (e.g. Uuid or integer keys); a custom info type whose Serialize impl can fail (e.g. serializing a value that exceeds f64 range); using a serde_json version where non-string keys hard-error instead of being coerced.","solutions":["Inspect the serde error in the message; find the info field value whose serialization failed.","Convert map keys to String before attaching the payload (e.g. HashMap<String, Value>, or .map(|(k,v)| (k.to_string(), v))).","If info holds non-JSON-representable data, serialize it yourself with a lossy conversion (serde_json::to_value(&value).unwrap_or(Value::Null)) or drop it before emitting the event.","Check the Serialize impl of any custom info type for fallible paths."],"exampleFix":"// before: non-string map keys break serde_json\nlet info = HashMap::<Uuid, String>::from([(order_id, \"ok\".to_string())]);\n\n// after: string keys serialize cleanly\nlet info = info.into_iter().map(|(k, v)| (k.to_string(), v)).collect::<HashMap<String, String>>();","handlingStrategy":"validation","validationCode":"// ensure info serializes before handing the event to the cache\nif let Some(info) = &event.info {\n    serde_json::to_value(info).expect(\"info must be JSON-serializable: use string map keys\");\n}","typeGuard":"fn is_json_serializable<T: serde::Serialize>(value: &T) -> bool {\n    serde_json::to_value(value).is_ok()\n}","tryCatchPattern":"let info_json = event.info.as_ref()\n    .map(serde_json::to_value)\n    .transpose()\n    .unwrap_or_else(|e| { log::warn!(\"info not serializable: {e}\"); None });","preventionTips":["Always use String keys in maps attached to event info payloads.","Never put NaN/infinite floats or non-JSON types in info.","Add a unit test that serializes a representative OrderFilled with populated info.","Keep custom Serialize impls infallible or return clear errors."],"tags":["serialization","serde","json","persistence"],"backgroundTag":"json-marshal-failed","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}