{"record":{"id":"365591f4591dfe51","repo":"nautechsystems/nautilus_trader","slug":"implement-fromrow-for-optionspread","errorCode":null,"errorMessage":"Implement FromRow for OptionSpread","messagePattern":"Implement FromRow for OptionSpread","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/infrastructure/src/sql/models/instruments.rs","lineNumber":1433,"sourceCode":"            .maybe_max_notional(max_notional)\n            .maybe_min_notional(min_notional)\n            .maybe_max_price(max_price)\n            .maybe_min_price(min_price)\n            .maybe_margin_init(margin_init)\n            .maybe_margin_maint(margin_maint)\n            .maybe_maker_fee(maker_fee)\n            .maybe_taker_fee(taker_fee)\n            .ts_event(ts_event)\n            .ts_init(ts_init)\n            .build()\n            .unwrap();\n        Ok(Self(inst))\n    }\n}\n\nimpl<'r> FromRow<'r, PgRow> for OptionSpreadRow {\n    fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {\n        todo!(\"Implement FromRow for OptionSpread\")\n    }\n}\n\nimpl<'r> FromRow<'r, PgRow> for CryptoFuturesSpreadRow {\n    #[expect(\n        clippy::too_many_lines,\n        reason = \"SQL row mapping mirrors the full crypto futures spread constructor\"\n    )]\n    fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {\n        let id = row.try_get::<String, _>(\"id\").map(InstrumentId::from)?;\n        let raw_symbol = row.try_get::<String, _>(\"raw_symbol\").map(Symbol::from)?;\n        let underlying = row.try_get::<String, _>(\"underlying\").map(Currency::from)?;\n        let quote_currency = row\n            .try_get::<String, _>(\"quote_currency\")\n            .map(Currency::from)?;\n        let settlement_currency = row\n            .try_get::<String, _>(\"settlement_currency\")\n            .map(Currency::from)?;","sourceCodeStart":1415,"sourceCodeEnd":1451,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/infrastructure/src/sql/models/instruments.rs#L1415-L1451","documentation":"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.","triggerScenarios":"Any sqlx decode of query results into OptionSpreadRow, e.g. loading option spread instruments from the database.","commonSituations":"Running an instrument sync/load that includes option spreads; writing a new query against the instruments schema with spread rows present.","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"],"exampleFix":"// before\nfn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {\n    todo!(\"Implement FromRow for OptionSpread\")\n}\n// after\nfn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {\n    let id = row.try_get::<String, _>(\"id\").map(InstrumentId::from)?;\n    // ... try_get all columns and construct the OptionSpread instrument\n    Ok(Self(inst))\n}","handlingStrategy":"validation","validationCode":"// Exclude option spreads from bulk loads\nif instrument.kind == OptionSpread { continue; }","typeGuard":null,"tryCatchPattern":"// Avoid decoding into OptionSpreadRow until implemented; filter at SQL level\nWHERE instrument_class != 'option_spread'","preventionTips":["Audit which row types have real FromRow impls before generic instrument sync","Track upstream implementation status of OptionSpread persistence"],"tags":["rust","sqlx","unimplemented","panic","database"],"backgroundTag":"method-not-implemented","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"}