nautechsystems/nautilus_trader · critical
Implement FromRow for OptionSpread
Error message
Implement FromRow for OptionSpread
What it means
Same placeholder pattern: `FromRow for OptionSpreadRow` is a `todo!()`, so decoding an option-spread instrument row from Postgres panics with this message. The surrounding CryptoFuturesSpreadRow impl is already written, making it the template to copy. Callers cannot catch this; it aborts the thread.
Source
Thrown at crates/infrastructure/src/sql/models/instruments.rs:1433
.maybe_max_notional(max_notional)
.maybe_min_notional(min_notional)
.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 OptionSpreadRow {
fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
todo!("Implement FromRow for OptionSpread")
}
}
impl<'r> FromRow<'r, PgRow> for CryptoFuturesSpreadRow {
#[expect(
clippy::too_many_lines,
reason = "SQL row mapping mirrors the full crypto futures spread constructor"
)]
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::from)?;
let underlying = row.try_get::<String, _>("underlying").map(Currency::from)?;
let quote_currency = row
.try_get::<String, _>("quote_currency")
.map(Currency::from)?;
let settlement_currency = row
.try_get::<String, _>("settlement_currency")
.map(Currency::from)?;View on GitHub (pinned to 18893faf8b)
Solutions
- Implement from_row for OptionSpreadRow following the adjacent OptionContractRow / CryptoFuturesSpreadRow implementations
- Exclude option spread rows from queries until implemented
- Track upstream as a known unimplemented persistence path
Example fix
// before
fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
todo!("Implement FromRow for OptionSpread")
}
// after
fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
let id = row.try_get::<String, _>("id").map(InstrumentId::from)?;
// ... try_get all columns and construct the OptionSpread instrument
Ok(Self(inst))
} Defensive patterns
Strategy: validation
Validate before calling
// Exclude option spreads from bulk loads
if instrument.kind == OptionSpread { continue; } Try / catch
// Avoid decoding into OptionSpreadRow until implemented; filter at SQL level WHERE instrument_class != 'option_spread'
Prevention
- Audit which row types have real FromRow impls before generic instrument sync
- Track upstream implementation status of OptionSpread persistence
When it happens
Trigger: Any sqlx decode of query results into OptionSpreadRow, e.g. loading option spread instruments from the database.
Common situations: Running an instrument sync/load that includes option spreads; writing a new query against the instruments schema with spread rows present.
Related errors
- Implement FromRow for FuturesSpread
- 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/365591f4591dfe51.
Report an issue: GitHub.