{"record":{"id":"55c9bdaf4a8cf763","repo":"nautechsystems/nautilus_trader","slug":"empty-book-snapshot-for-instrument-id","errorCode":null,"errorMessage":"Empty book snapshot for {instrument_id}","messagePattern":"Empty book snapshot for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/websocket/parse.rs","lineNumber":161,"sourceCode":"    neg_risk: bool,\n    last_trade_price: &'a str,\n}\n\n/// Parses a book snapshot into [`OrderBookDeltas`] (CLEAR + ADD).\npub fn parse_book_snapshot(\n    snap: &PolymarketBookSnapshot,\n    instrument_id: InstrumentId,\n    price_precision: u8,\n    size_precision: u8,\n    ts_init: UnixNanos,\n) -> anyhow::Result<OrderBookDeltas> {\n    let ts_event = parse_timestamp_ms(&snap.timestamp)?;\n\n    let bids_len = snap.bids.len();\n    let asks_len = snap.asks.len();\n\n    if bids_len == 0 && asks_len == 0 {\n        anyhow::bail!(\"Empty book snapshot for {instrument_id}\");\n    }\n\n    let total = bids_len + asks_len;\n    let mut deltas = Vec::with_capacity(total + 1);\n\n    // Every snapshot delta (including the opening CLEAR) carries F_SNAPSHOT so\n    // downstream consumers can recognize the rebuild; F_LAST closes the batch\n    // on the final delta. `OrderBookDelta::clear` already sets F_SNAPSHOT.\n    let snapshot_flag = RecordFlag::F_SNAPSHOT as u8;\n    deltas.push(OrderBookDelta::clear(instrument_id, 0, ts_event, ts_init));\n\n    let mut count = 0;\n\n    for level in &snap.bids {\n        count += 1;\n        let price = parse_price(&level.price, price_precision)?;\n        let size = parse_quantity(&level.size, size_precision)?;\n        let order = BookOrder::new(OrderSide::Buy, price, size, 0);","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/websocket/parse.rs#L143-L179","documentation":"parse_book_snapshot converts a Polymarket book snapshot into order book deltas; a snapshot with zero bids and zero asks carries no state the engine can apply, so it is rejected rather than producing an empty book. Empty snapshots usually indicate a market with no resting orders or an upstream glitch.","triggerScenarios":"Receiving a snapshot message where both bids and asks arrays are empty and passing it to parse_book_snapshot(instrument_id, snap, ...).","commonSituations":"Very new or illiquid markets with no resting orders; venue emitting an initial empty snapshot before seeding levels; a market that was paused/delisted mid-session.","solutions":["Treat the empty snapshot as a book clear/reset at the engine level instead of calling parse_book_snapshot, or skip and wait for a populated snapshot","Log asset_id/timestamp and check the market's status on the venue before subscribing","Retry the subscription — the venue typically follows with a populated snapshot","If empty books are legitimate for your market, relax the guard to emit an opening CLEAR delta only"],"exampleFix":"// before\nif bids_len == 0 && asks_len == 0 {\n    anyhow::bail!(\"Empty book snapshot for {instrument_id}\");\n}\n// after\nif bids_len == 0 && asks_len == 0 {\n    tracing::debug!(\"empty book snapshot for {instrument_id}; emitting clear only\");\n    return Ok(vec![OrderBookDelta::clear(instrument_id, book_sequence, ts_event, ts_init, F_SNAPSHOT)]);\n}","handlingStrategy":"validation","validationCode":"if snap.bids.is_empty() && snap.asks.is_empty() {\n    // skip or treat as clear; do not call parse_book_snapshot\n    return Ok(());\n}\nlet deltas = parse_book_snapshot(instrument_id, &snap, ts_init)?;","typeGuard":null,"tryCatchPattern":"match parse_book_snapshot(instrument_id, &snap, ts_init) {\n    Ok(deltas) => apply(deltas),\n    Err(e) if e.to_string().starts_with(\"Empty book snapshot\") => log::debug!(\"empty snapshot for {instrument_id}; ignoring\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Check bids/asks emptiness before parsing snapshots","Skip or clear-reset empty snapshots for illiquid/new markets","Confirm market status on the venue before subscribing"],"tags":["rust","order-book","parsing","polymarket"],"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-14T00:17:10.932Z"}