nautechsystems/nautilus_trader · error
Failed to serialize exec algorithm params: {e}
Error message
Failed to serialize exec algorithm params: {e} What it means
Raised by `add_order_event` when `order_event.exec_algorithm_params()` is `Some` but the value cannot be serialized to JSON via `serde_json::to_value`. This is a local serialization failure before any SQL executes, so the transaction is untouched. It indicates the params type contains data serde_json cannot represent (e.g., non-string map keys) or a custom serializer bug.
Source
Thrown at crates/infrastructure/src/sql/queries.rs:660
// TODO remove this when client initialization is implemented
if let Some(client_id) = client_id {
sqlx::query(
r#"
INSERT INTO "client" (id) VALUES ($1) ON CONFLICT (id) DO NOTHING
"#,
)
.bind(client_id.to_string())
.execute(&mut *transaction)
.await
.map(|_| ())
.map_err(|e| anyhow::anyhow!("Failed to insert into client table: {e}"))?;
}
let exec_algorithm_params = order_event
.exec_algorithm_params()
.map(serde_json::to_value)
.transpose()
.map_err(|e| anyhow::anyhow!("Failed to serialize exec algorithm params: {e}"))?;
let info = order_event
.info()
.map(serde_json::to_value)
.transpose()
.map_err(|e| anyhow::anyhow!("Failed to serialize order event info: {e}"))?;
sqlx::query(r#"
INSERT INTO "order_event" (
id, kind, client_order_id, order_type, order_side, trader_id, client_id, reason, strategy_id, instrument_id, trade_id, currency, quantity, time_in_force, liquidity_side,
post_only, reduce_only, quote_quantity, reconciliation, price, last_px, last_qty, trigger_price, trigger_type, limit_offset, trailing_offset,
trailing_offset_type, expire_time, display_qty, emulation_trigger, trigger_instrument_id, contingency_type,
order_list_id, linked_order_ids, parent_order_id,
exec_algorithm_id, exec_spawn_id, venue_order_id, account_id, position_id, commission, ts_event, ts_init, activation_price, exec_algorithm_params, tags,
released_price, protection_price, due_post_only, correction_id, is_reopened, info, causation_id, created_at, updated_at
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20,
$21, $22, $23, $24, $25, $26::trailing_offset_type, $27, $28, $29, $30, $31, $32, $33, $34,
$35, $36, $37, $38, $39, $40, $41, $42, $43, $44, $45, $46,View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect `{e}` (a `serde_json::Error`) for which value failed serialization.
- Change exec algorithm params to use string keys (e.g., `HashMap<String, T>`) so they are JSON-compatible.
- Fix or regenerate the `Serialize` implementation for the params type.
- Pre-test serialization with `serde_json::to_value(¶ms)` before persisting events.
Example fix
// before params: HashMap<u64, OrderFilled>, // after params: HashMap<String, OrderFilled>, // serde_json-compatible keys
Defensive patterns
Strategy: validation
Validate before calling
// Validate params are JSON-serializable before calling add_order_event
if let Some(params) = event.exec_algorithm_params() {
serde_json::to_value(params)
.map_err(|e| anyhow::anyhow!("exec params not JSON-serializable: {e}"))?;
} Type guard
fn is_json_serializable<T: serde::Serialize>(value: &T) -> bool {
serde_json::to_value(value).is_ok()
} Try / catch
// Prefer validation; if catching:
match serde_json::to_value(params) {
Ok(v) => { /* proceed */ }
Err(e) => log::error!("params serialization failed: {e}"),
} Prevention
- Use string-keyed maps in exec algorithm params.
- Add a unit test that round-trips params through serde_json.
- Keep serde and serde_json versions aligned across the workspace.
When it happens
Trigger: Calling `add_order_event` on an `OrderEventAny` whose exec algorithm params implement serialization in a way `serde_json` rejects — typically maps with non-string keys, or a Serialize impl returning an error.
Common situations: Custom exec algorithm params using `HashMap<u64, _>` or similar non-string keys; a broken hand-written `Serialize` implementation; version changes in serde_json dropping support for a previously-serialized shape.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- Failed to serialize order event info: {e}
- Failed to serialize config value: {e}
- Failed to decode position replay state: {e}
- Failed to serialize fill info: {e}
- Failed to serialize account event: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/fd3a553835d38b50.
Report an issue: GitHub.