nautechsystems/nautilus_trader · error
InstrumentId symbol is empty
Error message
InstrumentId symbol is empty
What it means
When converting an InstrumentId to a Bybit symbol, the adapter checks that the symbol component is non-empty. An InstrumentId with an empty symbol cannot map to a venue symbol, so the request is aborted.
Source
Thrown at crates/adapters/bybit/src/http/client.rs:4725
);
};
return self
.generate_spot_position_reports_from_wallet(account_id, instrument_id)
.await;
} else {
// Return empty vector when SPOT position reports are disabled
return Ok(Vec::new());
}
}
let ts_init = self.generate_ts_init();
let mut reports = Vec::new();
// Build query parameters based on whether a specific instrument is requested
let symbol = if let Some(id) = instrument_id {
let symbol_str = id.symbol.as_str();
if symbol_str.is_empty() {
anyhow::bail!("InstrumentId symbol is empty");
}
let bybit_symbol = BybitSymbol::new(symbol_str)?;
Some(bybit_symbol.raw_symbol().to_string())
} else {
None
};
// For LINEAR category, the API requires either symbol OR settleCoin
// When querying all positions (no symbol), we must iterate through settle coins
if product_type == BybitProductType::Linear && symbol.is_none() {
// Query positions for each known settle coin with pagination
for settle_coin in ["USDT", "USDC"] {
let mut cursor: Option<String> = None;
loop {
let params = BybitPositionListParams {
category: product_type,
symbol: None,View on GitHub (pinned to 18893faf8b)
Solutions
- Validate the symbol is non-empty before constructing the InstrumentId
- Trim and normalize venue symbols when building InstrumentIds
- Pass None instead of an empty-symbol InstrumentId when no specific instrument is intended
Example fix
// before
let id = InstrumentId::from(format!("@{}", venue).as_str()); // empty symbol
// after
anyhow::ensure!(!symbol.is_empty(), "symbol required");
let id = InstrumentId::from(format!("{symbol}@{venue").as_str()); Defensive patterns
Strategy: validation
Validate before calling
anyhow::ensure!(!instrument_id.symbol.as_str().is_empty(), "instrument symbol must be non-empty"); let bybit_symbol = BybitSymbol::new(instrument_id.symbol.as_str())?;
Type guard
fn has_symbol(id: &InstrumentId) -> bool { !id.symbol.as_str().is_empty() } Prevention
- Validate symbols when constructing InstrumentIds
- Trim venue metadata before symbol construction
- Pass None rather than an empty-symbol ID when the instrument is unknown
When it happens
Trigger: Passing an InstrumentId whose symbol part is an empty string (e.g. parsed from "@BYBIT.SPOT"-style or malformed input) into an instruments/positions query that expects Some(instrument_id).
Common situations: Programmatically constructed InstrumentIds where the symbol was built from an empty or untrimmed string; parsing venue metadata that returned blank symbols.
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
- Batch cancel limit is {endpoint_limit} orders for {product_t
- Invalid `external_order_claims` type: {e}
- Invalid `external_order_claims` instrument ID {claim}: {e}
- {FAILED}: {e}
- Cannot extract market ID from {instrument_id}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/38510c9635888e1f.
Report an issue: GitHub.