nautechsystems/nautilus_trader · error · anyhow::Error
quote_coin is empty for symbol '{}'
Error message
quote_coin is empty for symbol '{}' What it means
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.
Source
Thrown at crates/adapters/bybit/src/common/parse.rs:438
/// Parses a linear contract definition (perpetual or dated future) into a Nautilus instrument.
///
/// # Panics
///
/// Panics if the constructed instrument fails validation.
pub fn parse_linear_instrument(
definition: &BybitInstrumentLinear,
fee_rate: &BybitFeeRate,
ts_event: UnixNanos,
ts_init: UnixNanos,
) -> anyhow::Result<InstrumentAny> {
// Validate required fields
anyhow::ensure!(
!definition.base_coin.is_empty(),
"base_coin is empty for symbol '{}'",
definition.symbol
);
anyhow::ensure!(
!definition.quote_coin.is_empty(),
"quote_coin is empty for symbol '{}'",
definition.symbol
);
let base_currency = get_currency(definition.base_coin.as_str());
let quote_currency = get_currency(definition.quote_coin.as_str());
let settlement_currency = resolve_settlement_currency(
definition.settle_coin.as_str(),
base_currency,
quote_currency,
)?;
let symbol = BybitSymbol::new(format!("{}-LINEAR", definition.symbol))?;
let instrument_id = symbol.to_instrument_id();
let raw_symbol = Symbol::new(symbol.raw_symbol());
let price_increment = parse_price(&definition.price_filter.tick_size, "priceFilter.tickSize")?;View on GitHub (pinned to 18893faf8b)
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
Example fix
// before
let def = BybitInstrumentLinear { symbol: "ETHUSDT".into(), quote_coin: "".into(), ..raw };
let inst = parse_linear_instrument(&def, &fee, ts_event, ts_init)?;
// after
let def = BybitInstrumentLinear { symbol: "ETHUSDT".into(), quote_coin: "USDT".into(), ..raw };
let inst = parse_linear_instrument(&def, &fee, ts_event, ts_init)?; Defensive patterns
Strategy: validation
Validate before calling
if def.quote_coin.trim().is_empty() {
return Err(anyhow::anyhow!("quote_coin missing for {}", def.symbol));
} Type guard
fn has_quote_coin(def: &BybitInstrumentLinear) -> bool {
!def.quote_coin.trim().is_empty()
} Try / catch
match parse_linear_instrument(&def, &fee, ts_event, ts_init) {
Ok(inst) => instruments.push(inst),
Err(e) => { tracing::warn!(symbol = %def.symbol, "skipping instrument: {e:#}"); continue; }
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Partial exchange responses for new/delisted contracts; misconfigured field mapping in deserialization; fixtures copied from inverse instrument examples where quote semantics differ.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- base_coin is empty for symbol '{}'
- Invalid tickSize of 0 for symbol '{}', cannot create instrum
- invalid 'bbo_level': '{s}', expected 1, 2, 3, 4, or 5
- invalid 'take_profit' price: '{s}', expected a non-negative
- invalid 'stop_loss' price: '{s}', expected a non-negative va
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/46ebca724085481d.
Report an issue: GitHub.