nautechsystems/nautilus_trader · critical
Implement FromRow for FuturesSpread
Error message
Implement FromRow for FuturesSpread
What it means
This is a deliberate `todo!()` placeholder in `FromRow for FuturesSpreadRow`, meaning futures-spread instrument rows cannot yet be deserialized from Postgres. Any query returning FuturesSpreadRow via sqlx panics with this message instead of returning a row. It is unfinished implementation, not a runtime condition the caller caused.
Source
Thrown at crates/infrastructure/src/sql/models/instruments.rs:998
.maybe_max_quantity(max_quantity)
.maybe_min_quantity(min_quantity)
.maybe_max_price(max_price)
.maybe_min_price(min_price)
.maybe_margin_init(margin_init)
.maybe_margin_maint(margin_maint)
.maybe_maker_fee(maker_fee)
.maybe_taker_fee(taker_fee)
.ts_event(ts_event)
.ts_init(ts_init)
.build()
.unwrap();
Ok(Self(inst))
}
}
impl<'r> FromRow<'r, PgRow> for FuturesSpreadRow {
fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
todo!("Implement FromRow for FuturesSpread")
}
}
impl<'r> FromRow<'r, PgRow> for OptionContractRow {
fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
let id = row.try_get::<String, _>("id").map(InstrumentId::from)?;
let raw_symbol = row.try_get::<String, _>("raw_symbol").map(Symbol::new)?;
let asset_class = row
.try_get::<AssetClassPg, _>("asset_class")
.map(|res| res.0)?;
let exchange = row
.try_get::<Option<String>, _>("exchange")
.map(|res| res.map(|s| Ustr::from(s.as_str())))?;
let underlying = row
.try_get::<String, _>("underlying")
.map(|res| Ustr::from(res.as_str()))?;
let option_kind = row
.try_get::<String, _>("option_kind")View on GitHub (pinned to 18893faf8b)
Solutions
- Implement from_row for FuturesSpreadRow by try_get-ing each column and constructing the inner instrument (mirror the adjacent OptionContractRow impl)
- As a stopgap, filter queries to exclude futures spread rows until the impl lands
- Raise/track an upstream issue in nautilus_infrastructure that FuturesSpread persistence is unimplemented
Example fix
// before
fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
todo!("Implement FromRow for FuturesSpread")
}
// after
fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
let id = row.try_get::<String, _>("id").map(InstrumentId::from)?;
let raw_symbol = row.try_get::<String, _>("raw_symbol")?.into();
// ... try_get remaining columns, build InstrumentAny::FuturesSpread(...)
Ok(Self(inst))
} Defensive patterns
Strategy: validation
Validate before calling
// Guard before decoding
if matches!(instrument_def, InstrumentDef::FuturesSpread(_)) {
return Err("FuturesSpread persistence not implemented".into());
} Try / catch
// todo! panics cannot be caught safely; filter rows instead let rows: Vec<ContractRow> = sqlx::query(query).fetch_all(&pool).await?;
Prevention
- Check the adapter's supported instrument types before writing persistence queries
- Search the crate for todo!/unimplemented! in FromRow impls before relying on generic load-all code paths
When it happens
Trigger: Any sqlx query whose output is decoded into FuturesSpreadRow via PgRow, e.g. fetching futures spread instruments from the instruments table.
Common situations: Developer writes or runs a query loading futures spread instruments; a load-all instruments routine reaches the spread branch; integration test exercising instrument persistence for spreads.
Related errors
- Implement FromRow for OptionSpread
- Failed to load account events: {e}
- Execution transaction {transaction_hash} was not found for s
- Failed to load from execution_transaction table: {e}
- Failed to load instruments: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/c91587c8470236fa.
Report an issue: GitHub.