{"record":{"id":"3efed87bb6929627","repo":"nautechsystems/nautilus_trader","slug":"cryptooption-missing-option-type-field-for-instr","errorCode":null,"errorMessage":"CryptoOption missing `option_type` field for instrument: {}","messagePattern":"CryptoOption missing `option_type` field for instrument: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/tardis/src/http/instruments.rs","lineNumber":235,"sourceCode":"    info: &TardisInstrumentInfo,\n    instrument_id: InstrumentId,\n    raw_symbol: Symbol,\n    activation: UnixNanos,\n    expiration: UnixNanos,\n    price_increment: Price,\n    size_increment: Quantity,\n    multiplier: Option<Quantity>,\n    margin_init: Decimal,\n    margin_maint: Decimal,\n    maker_fee: Decimal,\n    taker_fee: Decimal,\n    ts_event: UnixNanos,\n    ts_init: UnixNanos,\n) -> anyhow::Result<InstrumentAny> {\n    let is_inverse = info.inverse.unwrap_or(false);\n\n    let option_type = info.option_type.ok_or_else(|| {\n        anyhow::anyhow!(\n            \"CryptoOption missing `option_type` field for instrument: {}\",\n            info.id\n        )\n    })?;\n\n    let strike_price = info.strike_price.ok_or_else(|| {\n        anyhow::anyhow!(\n            \"CryptoOption missing `strike_price` field for instrument: {}\",\n            info.id\n        )\n    })?;\n\n    Ok(InstrumentAny::CryptoOption(\n        CryptoOption::builder()\n            .instrument_id(instrument_id)\n            .raw_symbol(raw_symbol)\n            .underlying(get_currency(info.base_currency.to_uppercase().as_str()))\n            .quote_currency(get_currency(info.quote_currency.to_uppercase().as_str()))","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/tardis/src/http/instruments.rs#L217-L253","documentation":"Raised in create_crypto_option when the Tardis instrument info lacks the mandatory `option_type` field (Call/Put). A CryptoOption instrument cannot be constructed without knowing its type, so the parse fails and the instrument is skipped.","triggerScenarios":"Parsing an options instrument from the Tardis HTTP API whose info record has no `option_type` value — API payload missing the field or an unhandled contract kind.","commonSituations":"Tardis API schema change for a new/renamed exchange; options data fetched for an exchange whose metadata mapping omits option_type; version drift between adapter and Tardis API; exotic instruments the mapper doesn't recognize.","solutions":["Update the adapter's instrument mapping to populate option_type for that exchange.","Check for adapter/API version mismatch and upgrade the tardis adapter.","Inspect the raw Tardis response for the instrument id to confirm the field is truly absent.","Skip/report the unparseable instrument if it's not needed for your strategy."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Check the raw info before constructing options\nif info.option_type.is_none() {\n    log::warn!(\"skipping option {} with missing option_type\", info.id);\n}","typeGuard":"fn has_option_type(info: &TardisInstrumentInfo) -> bool {\n    info.option_type.is_some()\n}","tryCatchPattern":"match create_crypto_option(...) {\n    Ok(instr) => Some(instr),\n    Err(e) if e.to_string().contains(\"missing `option_type`\") => {\n        log::warn!(\"skipping option instrument: {e}\");\n        None\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Keep the adapter's exchange metadata mappings up to date with the Tardis API.","Log and skip unmappable instruments instead of aborting ingestion.","Test instrument parsing against live API samples per exchange after upgrades."],"tags":["instruments","parsing","options"],"backgroundTag":"missing-required-argument","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"}