{"record":{"id":"46ebca724085481d","repo":"nautechsystems/nautilus_trader","slug":"quote-coin-is-empty-for-symbol","errorCode":null,"errorMessage":"quote_coin is empty for symbol '{}'","messagePattern":"quote_coin is empty for symbol '(.+?)'","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/bybit/src/common/parse.rs","lineNumber":438,"sourceCode":"\n/// Parses a linear contract definition (perpetual or dated future) into a Nautilus instrument.\n///\n/// # Panics\n///\n/// Panics if the constructed instrument fails validation.\npub fn parse_linear_instrument(\n    definition: &BybitInstrumentLinear,\n    fee_rate: &BybitFeeRate,\n    ts_event: UnixNanos,\n    ts_init: UnixNanos,\n) -> anyhow::Result<InstrumentAny> {\n    // Validate required fields\n    anyhow::ensure!(\n        !definition.base_coin.is_empty(),\n        \"base_coin is empty for symbol '{}'\",\n        definition.symbol\n    );\n    anyhow::ensure!(\n        !definition.quote_coin.is_empty(),\n        \"quote_coin is empty for symbol '{}'\",\n        definition.symbol\n    );\n\n    let base_currency = get_currency(definition.base_coin.as_str());\n    let quote_currency = get_currency(definition.quote_coin.as_str());\n    let settlement_currency = resolve_settlement_currency(\n        definition.settle_coin.as_str(),\n        base_currency,\n        quote_currency,\n    )?;\n\n    let symbol = BybitSymbol::new(format!(\"{}-LINEAR\", definition.symbol))?;\n    let instrument_id = symbol.to_instrument_id();\n    let raw_symbol = Symbol::new(symbol.raw_symbol());\n\n    let price_increment = parse_price(&definition.price_filter.tick_size, \"priceFilter.tickSize\")?;","sourceCodeStart":420,"sourceCodeEnd":456,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bybit/src/common/parse.rs#L420-L456","documentation":"parse_linear_instrument requires quote_coin to be nonempty because it derives the quote Currency (e.g. USDT) and pricing/instrument metadata for linear instruments. An empty quote_coin indicates an incomplete Bybit instrument definition, so the parser rejects it with this error naming the symbol.","triggerScenarios":"Calling parse_linear_instrument with a BybitInstrumentLinear whose quote_coin is empty — e.g. the /v5/market/instruments-info payload omitted quote_coin, or a constructed definition in tests/adapters missed the field.","commonSituations":"Partial exchange responses for new/delisted contracts; misconfigured field mapping in deserialization; fixtures copied from inverse instrument examples where quote semantics differ.","solutions":["Verify the Bybit API response includes quote_coin for the symbol and fix the data source","Correct the deserialization struct mapping so quote_coin is populated","Skip instruments with empty quote_coin and log a warning instead of failing the batch","Update test fixtures to include realistic quote_coin values"],"exampleFix":"// before\nlet def = BybitInstrumentLinear { symbol: \"ETHUSDT\".into(), quote_coin: \"\".into(), ..raw };\nlet inst = parse_linear_instrument(&def, &fee, ts_event, ts_init)?;\n// after\nlet def = BybitInstrumentLinear { symbol: \"ETHUSDT\".into(), quote_coin: \"USDT\".into(), ..raw };\nlet inst = parse_linear_instrument(&def, &fee, ts_event, ts_init)?;","handlingStrategy":"validation","validationCode":"if def.quote_coin.trim().is_empty() {\n    return Err(anyhow::anyhow!(\"quote_coin missing for {}\", def.symbol));\n}","typeGuard":"fn has_quote_coin(def: &BybitInstrumentLinear) -> bool {\n    !def.quote_coin.trim().is_empty()\n}","tryCatchPattern":"match parse_linear_instrument(&def, &fee, ts_event, ts_init) {\n    Ok(inst) => instruments.push(inst),\n    Err(e) => { tracing::warn!(symbol = %def.symbol, \"skipping instrument: {e:#}\"); continue; }\n}","preventionTips":["Require quote_coin in deserialization (no serde default to empty)","Filter malformed instrument rows before batch parsing","Validate fixtures against the live API schema","Log and skip incomplete definitions during request_instruments"],"tags":["bybit","instrument-parsing","validation"],"backgroundTag":"empty-required-field","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"}