nautechsystems/nautilus_trader · error · anyhow::Error
Invalid OPRA option symbol: {symbol_str}
Error message
Invalid OPRA option symbol: {symbol_str} What it means
The Interactive Brokers adapter only accepts canonical OCC option symbols when the instrument venue is OPRA (e.g. AAPL 251212C00250000). This error is raised in instrument_id_to_ib_contract when the symbol fails the is_canonical_occ_option_symbol check, because IB contract construction for options depends on OCC-format fields (underlying, expiry, right, strike).
Source
Thrown at crates/adapters/interactive_brokers/src/common/parse.rs:662
if venue_matches(venue_str.as_str(), VENUES_CRYPTO)
&& let Some(captures) = parse_crypto_symbol(symbol_str)
{
return Ok(Contract {
contract_id: 0,
symbol: Symbol::from(&captures.base),
security_type: SecurityType::Crypto,
exchange: Exchange::from(exchange_str),
currency: Currency::from(&captures.quote),
local_symbol: format!("{}.{}", captures.base, captures.quote),
..Default::default()
});
}
// Handle Options (OPT)
if is_option_venue(venue_str.as_str()) {
if venue_str == "OPRA" {
if !is_canonical_occ_option_symbol(symbol_str) {
anyhow::bail!("Invalid OPRA option symbol: {symbol_str}");
}
return Ok(Contract {
contract_id: 0,
security_type: SecurityType::Option,
exchange: Exchange::from(exchange_str),
currency: Currency::from("USD"),
local_symbol: symbol_str.to_string(),
..Default::default()
});
}
if let Some(opt) = parse_option_symbol(symbol_str) {
return Ok(Contract {
contract_id: 0,
symbol: Symbol::from(&opt.symbol),
security_type: SecurityType::Option,
exchange: Exchange::from(exchange_str),View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the option symbol is the full 21-character OCC format (6-char underlying, 6-digit YYMMDD, C/P, 8-digit strike x1000)
- Build option InstrumentIds via the adapter's canonical conversion path rather than manual strings
- If using a non-OPRA venue, check the exchange mapping / venue so the OPRA branch is not entered
- If the symbol is a valid OCC name like a flexible symbol, verify is_canonical_occ_option_symbol semantics before converting
Example fix
// before
let instrument_id = InstrumentId::from("AAPL251212C00250000.OPRA");
// after (canonical OCC, 21 chars, padded underlying)
let instrument_id = InstrumentId::from("AAPL 251212C00250000.OPRA"); Defensive patterns
Strategy: validation
Validate before calling
fn is_canonical_occ_symbol(s: &str) -> bool {
s.len() == 21
&& s.as_bytes()[6..12].iter().all(u8::is_ascii_digit)
&& matches!(s.as_bytes()[12], b'C' | b'P')
&& s.as_bytes()[13..].iter().all(u8::is_ascii_digit)
} Try / catch
match instrument_id_to_ib_contract(&instrument_id) {
Ok(contract) => contract,
Err(e) if e.to_string().contains("Invalid OPRA option symbol") => {
eprintln!("symbol {} is not canonical OCC: {e}", instrument_id.symbol);
return;
}
Err(e) => return Err(e),
} Prevention
- Always use the canonical 21-character OCC format for OPRA option symbols
- Build option IDs through the library's conversion helpers, not by hand
- Unit-test option symbol parsing with padded underlyings and both C/P rights
When it happens
Trigger: Calling instrument_id_to_ib_contract with an InstrumentId whose venue is OPRA but whose symbol is not a 21-character canonical OCC symbol (e.g. truncated OCC, named-style symbols like 'AAPL US 12/12/25 C250', or a wrong-length padded symbol).
Common situations: Data feeds that emit non-OCRA option IDs, hand-built option InstrumentIds, symbol normalization that strips OCC padding, or tests constructing option IDs with alternative formats.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Unknown IB option right: {value}
- Invalid spread symbol format for component: {component}
- option_summary_family_subs mutex poisoned
- Invalid `OptionKind`, was '{invalid}'
- Invalid Hyperliquid outcome symbol '{symbol}': encoding must
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/fb01aaf0d3929a59.
Report an issue: GitHub.